<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是uboot——uboot源码顶层Makefile基础解析的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV05-02-U-Boot-06-01-顶层Makefile基础解析">
<meta property="og:url" content="https://sumumm.github.io/post/ca32061f.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是uboot——uboot源码顶层Makefile基础解析的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119220727685.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119221119307.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119231818010.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119232614054.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20230730143850408.png">
<meta property="article:published_time" content="2024-11-19T15:38:31.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:57.043Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV05-系统镜像">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119220727685.png">


<link rel="canonical" href="https://sumumm.github.io/post/ca32061f.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":"","permalink":"https://sumumm.github.io/post/ca32061f.html","path":"post/ca32061f.html","title":"LV05-02-U-Boot-06-01-顶层Makefile基础解析"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV05-02-U-Boot-06-01-顶层Makefile基础解析 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81U-Boot%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80"><span class="nav-text">一、U-Boot顶层Makefile基础</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E7%89%88%E6%9C%AC%E5%8F%B7"><span class="nav-text">1. 版本号</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-MAKEFLAGS-%E5%8F%98%E9%87%8F"><span class="nav-text">2. MAKEFLAGS 变量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E5%91%BD%E4%BB%A4%E8%BE%93%E5%87%BA"><span class="nav-text">3. 命令输出</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-%E9%BB%98%E8%AE%A4%E7%9A%84%E8%BE%93%E5%87%BA%E6%83%85%E5%86%B5"><span class="nav-text">3.1 默认的输出情况</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-%E5%AE%8C%E6%95%B4%E5%91%BD%E4%BB%A4%E8%BE%93%E5%87%BA"><span class="nav-text">3.2 完整命令输出</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-3-%E5%91%BD%E4%BB%A4%E8%BE%93%E5%87%BA%E6%8E%A7%E5%88%B6"><span class="nav-text">3.3 命令输出控制</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-3-1-%E5%91%BD%E4%BB%A4%E8%BE%93%E5%87%BA%E6%8E%A7%E5%88%B6%E5%91%BD%E4%BB%A4"><span class="nav-text">3.3.1 命令输出控制命令</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#3-3-2-V%E7%9A%84%E6%9D%A5%E6%BA%90"><span class="nav-text">3.3.2 V的来源</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-3-2-Q%E4%B8%8Equiet"><span class="nav-text">3.3.2 Q与quiet</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-4-%E6%80%8E%E4%B9%88%E6%8E%A7%E5%88%B6%E8%BE%93%E5%87%BA%E4%BF%A1%E6%81%AF%EF%BC%9F"><span class="nav-text">3.4 怎么控制输出信息？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-5-%E9%9D%99%E9%BB%98%E8%BE%93%E5%87%BA"><span class="nav-text">3.5 静默输出</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-1-%E9%9D%99%E9%BB%98%E8%BE%93%E5%87%BA%E5%91%BD%E4%BB%A4"><span class="nav-text">3.5.1 静默输出命令</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-2-make%E7%89%88%E6%9C%AC%E5%8F%B7%E5%88%A4%E6%96%AD"><span class="nav-text">3.5.2 make版本号判断</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-3-%E7%A1%AE%E5%AE%9Aquiet%E7%9A%84%E5%80%BC"><span class="nav-text">3.5.3 确定quiet的值</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-6-%E5%AF%BC%E5%87%BA%E5%8F%98%E9%87%8F"><span class="nav-text">3.6 导出变量</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E8%AE%BE%E7%BD%AE%E7%BC%96%E8%AF%91%E7%BB%93%E6%9E%9C%E8%BE%93%E5%87%BA%E7%9B%AE%E5%BD%95"><span class="nav-text">4. 设置编译结果输出目录</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-%E8%BE%93%E5%87%BA%E7%9B%AE%E5%BD%95%E6%8E%A7%E5%88%B6%E5%91%BD%E4%BB%A4"><span class="nav-text">4.1 输出目录控制命令 </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-O%E5%8F%82%E6%95%B0%E6%9D%A5%E6%BA%90%E5%88%A4%E6%96%AD"><span class="nav-text">4.2 O参数来源判断</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-%E5%88%9B%E5%BB%BAKBUILD-OUTPUT%E7%9B%AE%E5%BD%95"><span class="nav-text">4.3 创建KBUILD_OUTPUT目录</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5"><span class="nav-text">5. 代码检查</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#5-1-%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5%E6%8E%A7%E5%88%B6%E5%91%BD%E4%BB%A4"><span class="nav-text">5.1 代码检查控制命令</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-2-KBUILD-CHECKSRC"><span class="nav-text">5.2 KBUILD_CHECKSRC</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-%E6%A8%A1%E5%9D%97%E7%BC%96%E8%AF%91"><span class="nav-text">6. 模块编译</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#6-1-%E6%A8%A1%E5%9D%97%E7%BC%96%E8%AF%91%E5%91%BD%E4%BB%A4"><span class="nav-text">6.1 模块编译命令</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-2-KBUILD-EXTMOD"><span class="nav-text">6.2 KBUILD_EXTMOD</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-3-%E7%BC%96%E8%AF%91%E7%9B%AE%E6%A0%87"><span class="nav-text">6.3 编译目标</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-VPATH%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="nav-text">7. VPATH的配置</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#8-%E7%BC%96%E8%AF%91%E5%B9%B3%E5%8F%B0"><span class="nav-text">8. 编译平台</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#8-1-%E4%B8%BB%E6%9C%BA%E6%9E%B6%E6%9E%84-HOSTARCH"><span class="nav-text">8.1 主机架构 HOSTARCH</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-2-%E4%B8%BB%E6%9C%BA%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-HOSTOS"><span class="nav-text">8.2 主机操作系统 HOSTOS</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-3-%E5%AF%BC%E5%87%BAHOSTARCH%E5%92%8CHOSTOS"><span class="nav-text">8.3 导出HOSTARCH和HOSTOS</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-4-%E7%9B%AE%E6%A0%87%E6%9E%B6%E6%9E%84%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8"><span class="nav-text">8.4 目标架构和编译器</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#8-4-1-%E8%AE%BE%E7%BD%AE%E5%91%BD%E4%BB%A4"><span class="nav-text">8.4.1 设置命令</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-4-2-ARCH%E4%B8%8ECROSS-COMPILE"><span class="nav-text">8.4.2 ARCH与CROSS_COMPILE</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#9-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="nav-text">9. 配置文件</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#10-%E9%80%9A%E7%94%A8%E5%AE%9A%E4%B9%89"><span class="nav-text">10. 通用定义</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#10-1-Kbuild-include"><span class="nav-text">10.1 Kbuild.include</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#10-2-%E6%80%8E%E4%B9%88%E8%A2%AB%E5%8C%85%E5%90%AB%E5%88%B0Makefile%E4%B8%AD%EF%BC%9F"><span class="nav-text">10.2 怎么被包含到Makefile中？</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#11-%E7%9B%B8%E5%85%B3%E5%8F%98%E9%87%8F"><span class="nav-text">11. 相关变量</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#11-1-%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7%E5%8F%98%E9%87%8F"><span class="nav-text">11.1 交叉编译工具变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#11-2-%E7%BC%96%E8%AF%91%E9%80%89%E9%A1%B9"><span class="nav-text">11.2 编译选项</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#11-3-%E5%8F%98%E9%87%8F%E5%AF%BC%E5%87%BA"><span class="nav-text">11.3 变量导出</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81Makefile%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90"><span class="nav-text">二、Makefile过程分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-make-xxx-defconfig"><span class="nav-text">1.  make xxx_defconfig</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-%E7%89%88%E6%9C%AC%E4%B8%8E%E6%97%B6%E9%97%B4"><span class="nav-text">1.1 版本与时间</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-1-1-version-h"><span class="nav-text">1.1.1 version_h</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#1-1-2-timestamp-h"><span class="nav-text">1.1.2 timestamp_h</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-%E4%B8%89%E4%B8%AA%E5%8F%98%E9%87%8F"><span class="nav-text">1.2 三个变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-3-%E4%B8%89%E4%B8%AA%E5%8F%98%E9%87%8F%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="nav-text">1.3 三个变量的使用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-4-config"><span class="nav-text">1.4 %config</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-4-1-FORCE"><span class="nav-text">1.4.1 FORCE</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#1-4-2-scripts-basic"><span class="nav-text">1.4.2 scripts_basic</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#1-4-3-config%E5%B1%95%E5%BC%80"><span class="nav-text">1.4.3 %config展开</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-5-%E7%BC%96%E8%AF%91%E4%BF%A1%E6%81%AF"><span class="nav-text">1.5 编译信息</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-6-Makefile-build-%E8%84%9A%E6%9C%AC"><span class="nav-text">1.6 Makefile.build 脚本</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-6-1-scripts-basic-%E7%9B%AE%E6%A0%87%E5%AF%B9%E5%BA%94%E7%9A%84%E5%91%BD%E4%BB%A4"><span class="nav-text">1.6.1 scripts_basic 目标对应的命令</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#1-6-2-config-%E7%9B%AE%E6%A0%87%E5%AF%B9%E5%BA%94%E7%9A%84%E5%91%BD%E4%BB%A4"><span class="nav-text">1.6.2 %config 目标对应的命令</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-7-%E6%80%BB%E7%BB%93%E4%B8%80%E4%B8%8B"><span class="nav-text">1.7 总结一下</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-u-boot-bin%E7%9A%84%E7%94%9F%E6%88%90%E8%BF%87%E7%A8%8B"><span class="nav-text">2. u-boot.bin的生成过程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6"><span class="nav-text">2.1 目标文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-all%E7%9B%AE%E6%A0%87%E8%A7%84%E5%88%99"><span class="nav-text">2.2 all目标规则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-ALL-y"><span class="nav-text">2.3 ALL-y</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-4-u-boot-bin"><span class="nav-text">2.4 u-boot.bin</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-5-u-boot-dtb-bin"><span class="nav-text">2.5 u-boot-dtb.bin</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-5-1-%E4%BE%9D%E8%B5%96%E7%9B%AE%E6%A0%87"><span class="nav-text">2.5.1 依赖目标</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-5-2-u-boot"><span class="nav-text">2.5.2 u-boot</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#2-5-2-1-u-boot%E7%9A%84%E4%BE%9D%E8%B5%96"><span class="nav-text">2.5.2.1 u-boot的依赖</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-5-2-2-head-y"><span class="nav-text">2.5.2.2 head-y</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-5-2-3-libs-y"><span class="nav-text">2.5.2.3 libs-y</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-5-2-4-u-boot-lds%E8%A7%84%E5%88%99"><span class="nav-text">2.5.2.4 u-boot.lds规则</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-5-2-5-built-in-o%E6%80%8E%E4%B9%88%E7%94%9F%E6%88%90%EF%BC%9F"><span class="nav-text">2.5.2.5  built-in.o怎么生成？</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-5-2-6-u-boot%E7%9A%84%E7%94%9F%E6%88%90"><span class="nav-text">2.5.2.6 u-boot的生成</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-6-%E6%80%BB%E7%BB%93%E4%B8%80%E4%B8%8B"><span class="nav-text">2.6 总结一下</span></a></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/ca32061f.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV05-02-U-Boot-06-01-顶层Makefile基础解析 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV05-02-U-Boot-06-01-顶层Makefile基础解析
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2024-11-19 23:38:31" itemprop="dateCreated datePublished" datetime="2024-11-19T23:38:31+08:00">2024-11-19</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/" itemprop="url" rel="index"><span itemprop="name">02IMX6ULL平台</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/" itemprop="url" rel="index"><span itemprop="name">LV05-系统镜像</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>12k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>44 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是uboot——uboot源码顶层Makefile基础解析的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" rowspan="5">PC端开发环境</td>        <td align="center" width=150px>Windows</td>        <td align="left">Windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu20.04.2的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 17 Pro</td>        <td align="left">17.6.0 build-24238078</td>      </tr>    <tr>        <td align="center">终端软件</td>        <td align="left">MobaXterm(Professional Edition v23.0 Build 5042 (license))</td>    </tr>    <tr>        <td align="center">Win32DiskImager</td>        <td align="left">Win32DiskImager v1.0</td>      </tr>    <tr>        <td align="center" rowspan="3">Linux开发板环境</td>        <td align="center">Linux开发板</td>        <td align="left">正点原子 i.MX6ULL Linux 阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，使用的uboot版本为U-Boot 2019.04</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.19.71(NXP官方提供)</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center">分类</td>        <td align="center">网址</td>        <td align="center">说明</td>    </tr>    <tr>        <td align="center" rowspan="5">官方网站</td>        <td align="left"><a href="https://www.arm.com/" target="_blank">https://www.arm.com/</a></td>        <td align="left">ARM官方网站，在这里我们可以找到Cotex-Mx以及ARMVx的一些文档</td>    </tr>    <tr>        <td align="left"><a href="https://www.nxp.com.cn/" target="_blank">https://www.nxp.com.cn/ </a></td>        <td align="left">NXP官方网站</td>    </tr>    <tr>        <td align="left"><a href="https://www.nxpic.org.cn/" target="_blank">https://www.nxpic.org.cn/</a></td><td align="left">NXP 官方社区</td>    </tr>    <tr>        <td align="left"><a href="https://u-boot.readthedocs.io/en/latest/" target="_blank">https://u-boot.readthedocs.io/en/latest/</a></td><td align="left">u-boot官网</td>    </tr>    <tr>        <td align="left"><a href="https://www.kernel.org/" target="_blank">https://www.kernel.org/</a></td><td align="left">linux内核官网</td>    </tr>    <tr>        <td align="center" rowspan="5">其他网站</td>        <td align="left"><a href="https://elixir.bootlin.com/linux/v4.15/source/kernel" target="_blank">kernel - Linux source code (v4.15) - Bootlin</a></td>        <td align="left">linux内核源码在线查看</td>    </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center">分类</td>        <td align="center">网址</td>        <td align="center">说明</td>    </tr>    <tr>        <td align="center" rowspan="3">NXP</td>        <td align="left"><a href="https://github.com/nxp-imx" target="_blank">https://github.com/nxp-imx</a></td>        <td align="left">NXP imx开发资源GitHub组织，里边会有u-boot和linux内核的仓库</td>    </tr>    <tr>        <td align="left"><a href="https://github.com/nxp-imx/linux-imx/releases/tag/v4.19.71" target="_blank">nxp-imx/linux-imx/releases/tag/v4.19.71</a></td>        <td align="left">NXP linux内核仓库tags中的v4.19.71</td>    </tr>    <tr>        <td align="left"><a href="https://github.com/nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0" target="_blank">nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0</a></td>        <td align="left">NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0</td>    </tr>    <tr>        <td align="center" rowspan="2">I.MX6ULL</td>        <td align="left"><a href="https://www.nxp.com.cn/docs/en/data-sheet/IMX6ULLIEC.pdf" target="_blank">i.MX 6ULL Applications Processors for Industrial Products</a></td>        <td align="left">I.MX6ULL 芯片手册（datasheet，可以在线查看）</td>    </tr>    <tr>        <td align="left"><a href="https://www.nxp.com.cn/webapp/Download?colCode=IMX6ULLRM&lang_cd=zh" target="_blank">i.MX 6ULL Applications ProcessorReference Manual</a></td>        <td align="left">I.MX6ULL 参考手册（下载后才能查看，需要登录NXP官网）</td>    </tr>    <tr>        <td align="center" rowspan="2">Source Code</td>        <td align="left"><a href="https://elixir.bootlin.com/linux/latest/source" target="_blank">https://elixir.bootlin.com/linux/latest/source</a></td>        <td align="left">linux kernel源码</td>    </tr>    <tr>        <td align="left"><a href="https://elixir.bootlin.com/u-boot/latest/source" target="_blank">https://elixir.bootlin.com/u-boot/latest/source</a></td>        <td align="left">uboot源码</td>    </tr></table>
              </div>
            </details>

<h1 id="一、U-Boot顶层Makefile基础"><a href="#一、U-Boot顶层Makefile基础" class="headerlink" title="一、U-Boot顶层Makefile基础"></a><font size=3>一、U-Boot顶层Makefile基础</font></h1><h2 id="1-版本号"><a href="#1-版本号" class="headerlink" title="1. 版本号"></a><font size=3>1. 版本号</font></h2><p>版本号定义在这里：<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L3">Makefile</a></p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">VERSION = 2019</span><br><span class="line">PATCHLEVEL = 04</span><br><span class="line">SUBLEVEL =</span><br><span class="line">EXTRAVERSION =</span><br><span class="line">NAME =</span><br></pre></td></tr></table></figure>

<p>VERSION 是主版本号，PATCHLEVEL 是补丁版本号，SUBLEVEL 是次版本号，这三个一 起构成了 uboot 的版本号，比如当前的 uboot 版本号就是“2019.04”。EXTRAVERSION 是附加 版本信息，NAME 是和名字有关的，一般不使用这两个。</p>
<h2 id="2-MAKEFLAGS-变量"><a href="#2-MAKEFLAGS-变量" class="headerlink" title="2. MAKEFLAGS 变量"></a><font size=3>2. MAKEFLAGS 变量</font></h2><p>make 是支持递归调用的，也就是在 Makefile 中使用“make”命令来执行其他的 Makefile 文件，一般都是子目录中的 Makefile 文件。假如在当前目录下存在一个“subdir”子目录，这个 子目录中又有其对应的 Makefile 文件，那么这个工程在编译的时候其主目录中的 Makefile 就可 以调用子目录中的 Makefile，以此来完成所有子目录的编译。主目录的 Makefile 可以使用如下代码来编译这个子目录：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(MAKE)</span> -C subdir</span><br></pre></td></tr></table></figure>

<p>$(MAKE)就是调用“make”命令，-C 指定子目录。有时候我们需要向子 make 传递变量， 这个时候使用“export”来导出要传递给子 make 的变量即可，如果不希望哪个变量传递给子 make 的话就使用“unexport”来声明不导出：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> VARIABLE   <span class="comment"># 导出变量给子 make </span></span><br><span class="line"><span class="keyword">unexport</span> VARIABLE <span class="comment"># 不导出变量给子 make</span></span><br></pre></td></tr></table></figure>

<p>有两个特殊的变量：“SHELL”和“MAKEFLAGS”，这两个变量除非使用“unexport”声明， 否则的话在整个make的执行过程中，它们的值始终自动的传递给子make。在uboot的主 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L18">Makefile</a> 中有如下代码：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MAKEFLAGS += -rR --include-dir=<span class="variable">$(CURDIR)</span></span><br></pre></td></tr></table></figure>

<p>上述代码使用“+&#x3D;”来给变量 MAKEFLAGS 追加了一些值，“-rR”表示禁止使用内置的隐 含规则和变量定义，“–include-dir”指明搜索路径，”$(CURDIR)”表示当前目录。</p>
<h2 id="3-命令输出"><a href="#3-命令输出" class="headerlink" title="3. 命令输出"></a><font size=3>3. 命令输出</font></h2><h3 id="3-1-默认的输出情况"><a href="#3-1-默认的输出情况" class="headerlink" title="3.1 默认的输出情况"></a><font size=3>3.1 默认的输出情况</font></h3><p>uboot 默认编译是不会在终端中显示完整的命令，都是短命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$  make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16</span><br><span class="line">scripts/kconfig/conf  --syncconfig Kconfig</span><br><span class="line">  CHK     include/config.h</span><br><span class="line">  UPD     include/config.h</span><br><span class="line">  GEN     include/autoconf.mk.dep</span><br><span class="line">  CFG     u-boot.cfg</span><br><span class="line">  GEN     include/autoconf.mk</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">*** Your GCC is older than 6.0 and will not be supported</span><br><span class="line">  HOSTCC  scripts/dtc/dtc.o</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">  HOSTCC  tools/zynqimage.o</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">  LD      fs/fat/built-in.o</span><br><span class="line">  CC      lib/efi_loader/efi_unicode_collation.o</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">  OBJCOPY u-boot.srec</span><br><span class="line">  SYM     u-boot.sym</span><br><span class="line">  DTC     arch/arm/dts/imx6ull-14x14-ddr3-arm2.dtb</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">  COPY    u-boot.dtb</span><br><span class="line">  COPY    u-boot.bin</span><br><span class="line">  CFGS    u-boot-dtb.cfgout</span><br><span class="line">  MKIMAGE u-boot-dtb.imx</span><br><span class="line">  CFGCHK  u-boot.cfg</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>在终端中输出短命令虽然看起来很清爽，但是不利于分析 uboot 的编译过程。</p>
<h3 id="3-2-完整命令输出"><a href="#3-2-完整命令输出" class="headerlink" title="3.2 完整命令输出"></a><font size=3>3.2 完整命令输出</font></h3><p>可以通过设 置变量“V&#x3D;1“来实现完整的命令输出，这个在调试 uboot 的时候很有用：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$  make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16</span><br><span class="line">make -f ./Makefile syncconfig</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">......</span></span><br><span class="line">make -f ./scripts/Makefile.build obj=scripts/kconfig syncconfig</span><br><span class="line">mkdir -p include/config include/generated</span><br><span class="line">scripts/kconfig/conf  --syncconfig Kconfig</span><br><span class="line">make -f ./scripts/Makefile.autoconf || \</span><br><span class="line">	&#123; rm -f include/config/auto.conf; false; &#125;</span><br><span class="line">if [ -d arch/arm/mach-mx6/include/mach ]; then	\</span><br><span class="line">	dest=../../mach-mx6/include/mach;			\</span><br><span class="line">else								\</span><br><span class="line">	dest=arch-mx6;			\</span><br><span class="line">fi;								\</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">*** Your GCC is older than 6.0 and will not be supported</span><br><span class="line">make -f ./scripts/Makefile.build obj=scripts</span><br><span class="line">make -f ./scripts/Makefile.build obj=scripts/dtc</span><br><span class="line">  cc -Wp,-MD,scripts/dtc/.dtc.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer  -std=gnu11    -Iscripts/dtc -Iscripts/dtc/libfdt -c -o scripts/dtc/dtc.o scripts/dtc/dtc.c</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">make -f ./scripts/Makefile.build obj=arch/arm/mach-imx u-boot-dtb.imx</span><br><span class="line">  cp u-boot-dtb.bin u-boot.bin</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">......</span></span><br><span class="line">  ./tools/mkimage -n u-boot-dtb.cfgout -T imximage -e 0x87800000 -d u-boot-dtb.bin u-boot-dtb.imx &gt;u-boot-dtb.imx.log  &amp;&amp; cat u-boot-dtb.imx.log</span><br><span class="line">Image Type:   Freescale IMX Boot Image</span><br><span class="line">Image Ver:    2 (i.MX53/6/7 compatible)</span><br><span class="line">Mode:         DCD</span><br><span class="line">Data Size:    675840 Bytes = 660.00 KiB = 0.64 MiB</span><br><span class="line">Load Address: 877ff420</span><br><span class="line">Entry Point:  87800000</span><br><span class="line">  ./scripts/check-config.sh u-boot.cfg ./scripts/config_whitelist.txt .</span><br></pre></td></tr></table></figure>

<h3 id="3-3-命令输出控制"><a href="#3-3-命令输出控制" class="headerlink" title="3.3 命令输出控制"></a><font size=3>3.3 命令输出控制</font></h3><h4 id="3-3-1-命令输出控制命令"><a href="#3-3-1-命令输出控制命令" class="headerlink" title="3.3.1 命令输出控制命令"></a><font size=3>3.3.1 命令输出控制命令</font></h4><p>顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L71">Makefile</a> 中控制命令输出的代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="string">&quot;$(origin V)&quot;</span>, <span class="string">&quot;command line&quot;</span>)</span><br><span class="line">  KBUILD_VERBOSE = <span class="variable">$(V)</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">ifndef</span> KBUILD_VERBOSE</span><br><span class="line">  KBUILD_VERBOSE = 0</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_VERBOSE)</span>,1)</span><br><span class="line">  quiet =</span><br><span class="line">  Q =</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  quiet=quiet_</span><br><span class="line">  Q = @</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<h5 id="3-3-2-V的来源"><a href="#3-3-2-V的来源" class="headerlink" title="3.3.2 V的来源"></a><font size=3>3.3.2 V的来源</font></h5><p>V的来源在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L71">Makefile</a>中是这一部分：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="string">&quot;$(origin V)&quot;</span>, <span class="string">&quot;command line&quot;</span>)</span><br><span class="line">  KBUILD_VERBOSE = <span class="variable">$(V)</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">ifndef</span> KBUILD_VERBOSE</span><br><span class="line">  KBUILD_VERBOSE = 0</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>上述代码中先使用 ifeq 来判断<code>&quot;$(origin V)&quot;</code>和<code>&quot;command line&quot;</code>是否相等。这里用到了 Makefile 中的函数 origin，origin 和其他的函数不一样，它不操作变量的值，origin 用于告诉你变量是哪来的，语法为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">origin</span> &lt;variable&gt;)</span></span><br></pre></td></tr></table></figure>

<p>variable 是变量名，origin 函数的返回值就是变量来源，因此<code>$(origin V)</code>就是变量 V 的来源。 如果变量 V 是在命令行定义的那么它的来源就是<code>&quot;command line&quot;</code>，这样<code>&quot;$(origin V)&quot;</code>和<code>&quot;command line&quot;</code>就相等了。当这两个相等的时候变量 KBUILD_VERBOSE 就等于 V 的值，比如在命令行中 输入“ V&#x3D;1 “ 的 话 那 么 KBUILD_VERBOSE&#x3D;1 。如果没有在命令行输入 V 的话 KBUILD_VERBOSE&#x3D;0。</p>
<h4 id="3-3-2-Q与quiet"><a href="#3-3-2-Q与quiet" class="headerlink" title="3.3.2 Q与quiet"></a><font size=3>3.3.2 Q与quiet</font></h4><p>这两个变量的控制在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L78">Makefile</a>中是这一部分：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_VERBOSE)</span>,1)</span><br><span class="line">  quiet =</span><br><span class="line">  Q =</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  quiet=quiet_</span><br><span class="line">  Q = @</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>判断 KBUILD_VERBOSE 是否为 1，如果 KBUILD_VERBOSE 为 1 的话变量 quiet和 Q 都为空，如果 KBUILD_VERBOSE&#x3D;0 的话变量 quiet 为“quiet_“，变量 Q 为“@”，所以V的作用是：</p>
<ul>
<li>V &#x3D; 1</li>
</ul>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">KBUILD_VERBOSE=1</span><br><span class="line">quiet=空</span><br><span class="line">Q=空</span><br></pre></td></tr></table></figure>

<ul>
<li>V &#x3D; 0 或者命令行不定义 V</li>
</ul>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">KBUILD_VERBOSE=0</span><br><span class="line">quiet= quiet_</span><br><span class="line">Q=@</span><br></pre></td></tr></table></figure>

<h3 id="3-4-怎么控制输出信息？"><a href="#3-4-怎么控制输出信息？" class="headerlink" title="3.4 怎么控制输出信息？"></a><font size=3>3.4 怎么控制输出信息？</font></h3><p>Makefile 中会用到变量 quiet 和 Q 来控制编译的时候是否在终端输出完整的命令，在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1722">Makefile</a> 中有很多如下所示的命令：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">tools-only: scripts_basic <span class="variable">$(version_h)</span> <span class="variable">$(timestamp_h)</span></span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> <span class="variable">$(build)</span>=tools</span><br></pre></td></tr></table></figure>

<p>如果 V&#x3D;0 的话上述命令展开就是：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@ make <span class="variable">$(build)</span>=tools</span><br></pre></td></tr></table></figure>

<p>make 在执行的时候默认会在终 端输出命令，但是在命令前面加上“@”就不会在终端输出命令了。</p>
<p>当 V&#x3D;1 的时候 Q 就为空， 上述命令就是：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make <span class="variable">$(build)</span>=tools</span><br></pre></td></tr></table></figure>

<p>此时在 make 执行的过程，命令会被完整的输出在终端上。</p>
<p>有些命令会有两个版本，比如 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1515">Makefile</a> 中的：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">quiet_cmd_sym ?= SYM     <span class="variable">$@</span></span><br><span class="line">      cmd_sym ?= <span class="variable">$(OBJDUMP)</span> -t <span class="variable">$&lt;</span> &gt; <span class="variable">$@</span></span><br></pre></td></tr></table></figure>

<p>sym 命令分为“quiet_cmd_sym”和“cmd_sym”两个版本，这两个命令的功能都是一样的， 区别在于 make 执行的时候输出的命令不同。quiet_cmd_xxx 命令输出信息少，也就是短命令， 而 cmd_xxx 命令输出信息多，也就是完整的命令。 如果变量 quiet 为空的话，整个命令都会输出。 如果变量 quiet 为“quiet_”的话，仅输出短版本。 如果变量 quiet 为“silent_”的话，整个命令都不会输出。这部分在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L45">Makefile - <em>Beautify output</em></a> 中有说明。</p>
<h3 id="3-5-静默输出"><a href="#3-5-静默输出" class="headerlink" title="3.5 静默输出"></a><font size=3>3.5 静默输出</font></h3><h4 id="3-5-1-静默输出命令"><a href="#3-5-1-静默输出命令" class="headerlink" title="3.5.1 静默输出命令"></a><font size=3>3.5.1 静默输出命令</font></h4><p>设置 V&#x3D;0 或者在命令行中不定义 V 的话，编译 uboot 的时候终端中显示的短命令，但是还是会有命令输出，有时候我们在编译 uboot 的时候不需要输出命令，这个时候 就可以使用 uboot 的静默输出功能。编译的时候使用这个命令就可以实现：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make -s</span><br></pre></td></tr></table></figure>

<p>即可实现静默输出，顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L86">Makefile</a> 中相应的代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># If the user is running make -s (silent mode), suppress echoing of</span></span><br><span class="line"><span class="comment"># commands</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> 4.%,<span class="variable">$(MAKE_VERSION)</span>)</span>,)	<span class="comment"># make-4</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> %s ,$(<span class="built_in">firstword</span> x<span class="variable">$(MAKEFLAGS)</span>)</span>),)</span><br><span class="line">  quiet=silent_</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">else</span>					<span class="comment"># make-3.8x</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> s% -s%,<span class="variable">$(MAKEFLAGS)</span>)</span>,)</span><br><span class="line">  quiet=silent_</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<h4 id="3-5-2-make版本号判断"><a href="#3-5-2-make版本号判断" class="headerlink" title="3.5.2 make版本号判断"></a><font size=3>3.5.2 make版本号判断</font></h4><p>先看<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L89">Makefile</a> 这一部分：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> 4.%,<span class="variable">$(MAKE_VERSION)</span>)</span>,)	<span class="comment"># make-4</span></span><br><span class="line"><span class="comment"># (1)......</span></span><br><span class="line"><span class="keyword">else</span>					<span class="comment"># make-3.8x</span></span><br><span class="line"><span class="comment"># (2)......</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>这里在判断当前正在使用的make命令版本号是否为 4.x，首先进行如下判断：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">判断 <span class="variable">$(<span class="built_in">filter</span> 4.%,<span class="variable">$(MAKE_VERSION)</span>)</span> 和 <span class="string">&quot; &quot;</span>(空)是否相等？</span><br></pre></td></tr></table></figure>

<p>如果不相等的话就成立，执行里面的(1)语句。这里用到了 Makefile 中的 filter 函数，这是 个过滤函数，函数格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">filter</span> &lt;pattern...&gt;,&lt;text&gt;)</span></span><br></pre></td></tr></table></figure>

<p>filter 函数表示以 pattern 模式过滤 text 字符串中的单词，仅保留符合模式 pattern 的单词， 可以有多个模式。函数返回值就是符合 pattern 的字符串。</p>
<p>因此<code>$(filter 4.%,$(MAKE_VERSION)) </code>的含义就是在字符串 “MAKE_VERSION” 中找出符合“4.%”的字符(%为通配符)， MAKE_VERSION 是make工具的版本号，ubuntu16.04里面默认自带的make工具版本号为4.1，之后的版本应该都是4.1及以上了， 我们可以在ubuntu中输入“make -v”查看。所以：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">filter</span> 4.%,<span class="variable">$(MAKE_VERSION)</span>)</span> != <span class="string">&quot; &quot;</span></span><br></pre></td></tr></table></figure>

<p>这里条件成立。后续走（1）处的语句。</p>
<h4 id="3-5-3-确定quiet的值"><a href="#3-5-3-确定quiet的值" class="headerlink" title="3.5.3 确定quiet的值"></a><font size=3>3.5.3 确定quiet的值</font></h4><p>上面我们已经确认条件成立，所以接下来走的是 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L90">Makefile</a> 这一部分的命令：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> 4.%,<span class="variable">$(MAKE_VERSION)</span>)</span>,)	<span class="comment"># make-4</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> %s ,$(<span class="built_in">firstword</span> x<span class="variable">$(MAKEFLAGS)</span>)</span>),)</span><br><span class="line">  quiet=silent_</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">else</span>					<span class="comment"># make-3.8x</span></span><br><span class="line"><span class="comment"># ......</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>这里也是一个判断语句</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">filter</span> %s ,$(<span class="built_in">firstword</span> x<span class="variable">$(MAKEFLAGS)</span>)</span>) != <span class="string">&quot; &quot;</span> (空)</span><br></pre></td></tr></table></figure>

<p>如果上面的条件成立，变量 quiet 等于“silent_”。这里也用到了函数 filter：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">firstword</span> x<span class="variable">$(MAKEFLAGS)</span>)</span>)</span><br></pre></td></tr></table></figure>

<p>在上面这个函数中过滤出符合“%s”的单词。到了函数 firstword，函数 firstword 是获取首单词，函数格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">firstword</span> &lt;text&gt;)</span></span><br></pre></td></tr></table></figure>

<p>firstword 函数用于取出 text 字符串中的第一个单词，函数的返回值就是获取到的单词。当 使用“make -s”编译的时候，“-s”会作为 MAKEFLAGS 变量的一部分传递给 Makefile。在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L98">Makefile</a> 的这段命令之后添加以下代码：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> 4.%,<span class="variable">$(MAKE_VERSION)</span>)</span>,)	<span class="comment"># make-4</span></span><br><span class="line"><span class="comment">#......</span></span><br><span class="line"><span class="keyword">else</span>					<span class="comment"># make-3.8x</span></span><br><span class="line"><span class="comment"># ......</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="section">my_test:</span></span><br><span class="line">	@echo <span class="string">&quot;first word=&quot;</span><span class="variable">$(<span class="built_in">firstword</span> x<span class="variable">$(MAKEFLAGS)</span>)</span></span><br></pre></td></tr></table></figure>

<p>然后我们在源码目录执行以下命令，看一下这个到底输出的是啥：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$  make -s ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- my_test -j16</span><br><span class="line">first word=xrRs</span><br></pre></td></tr></table></figure>

<p>从输出可以看出第一个单词是“xrRs”，把下面的命令展开</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">filter</span> %s ,$(<span class="built_in">firstword</span> x<span class="variable">$(MAKEFLAGS)</span>)</span>) </span><br><span class="line"><span class="comment"># 展开就是</span></span><br><span class="line"><span class="variable">$(<span class="built_in">filter</span> %s, xrRs)</span></span><br></pre></td></tr></table></figure>

<p>而$(filter %s, xrRs)的返回值肯定不为空，条件成立，所以quiet&#x3D;silent_。 </p>
<h3 id="3-6-导出变量"><a href="#3-6-导出变量" class="headerlink" title="3.6 导出变量"></a><font size=3>3.6 导出变量</font></h3><p>上面关于命令输出的变量的值都已经确定完毕了，最后使用export命令导出，导出命令在这里：<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L99">Makefile</a></p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> quiet Q KBUILD_VERBOSE</span><br></pre></td></tr></table></figure>

<p>使用 export 导出变量 quiet、Q 和 KBUILD_VERBOSE。</p>
<h2 id="4-设置编译结果输出目录"><a href="#4-设置编译结果输出目录" class="headerlink" title="4. 设置编译结果输出目录"></a><font size=3>4. 设置编译结果输出目录</font></h2><h3 id="4-1-输出目录控制命令"><a href="#4-1-输出目录控制命令" class="headerlink" title="4.1 输出目录控制命令 "></a><font size=3>4.1 输出目录控制命令 </font></h3><p>uboot 可以将编译出来的目标文件输出到单独的目录中，在 make 的时候使用“O”来指定 输出目录。比如：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make O=out</span><br></pre></td></tr></table></figure>

<p>就是设置目标文件输出到 out 目录中。这么做是为了将源文件和编译产生的文件分开，当然也可以不指定 O 参数，不指定的话源文件和编译产生的文件都在 同一个目录内，一般在进行uboot编译的时候我们不指定 O 参数。在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L101">Makefile</a> 中实现设置输出目录的代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ......</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_SRC)</span>,)</span><br><span class="line"></span><br><span class="line"><span class="comment"># OK, Make called in directory where kernel src resides</span></span><br><span class="line"><span class="comment"># Do we want to locate output files in a separate directory?</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="string">&quot;$(origin O)&quot;</span>, <span class="string">&quot;command line&quot;</span>)</span><br><span class="line">  KBUILD_OUTPUT := <span class="variable">$(O)</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># That&#x27;s our default target when none is given on the command line</span></span><br><span class="line">PHONY := _all</span><br><span class="line"><span class="section">_all:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Cancel implicit rules on top Makefile</span></span><br><span class="line"><span class="variable">$(CURDIR)</span>/Makefile Makefile: ;</span><br><span class="line"></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(KBUILD_OUTPUT)</span>,)</span><br><span class="line"><span class="comment"># Invoke a second make in the output directory, passing relevant variables</span></span><br><span class="line"><span class="comment"># check that the output directory actually exists</span></span><br><span class="line">saved-output := <span class="variable">$(KBUILD_OUTPUT)</span></span><br><span class="line">KBUILD_OUTPUT := <span class="variable">$(<span class="built_in">shell</span> mkdir -p <span class="variable">$(KBUILD_OUTPUT)</span> &amp;&amp; cd <span class="variable">$(KBUILD_OUTPUT)</span> \</span></span><br><span class="line"><span class="variable">								&amp;&amp; /bin/pwd)</span></span><br><span class="line"><span class="variable">$(<span class="built_in">if</span> <span class="variable">$(KBUILD_OUTPUT)</span>,, \</span></span><br><span class="line"><span class="variable">     $(<span class="built_in">error</span> failed to create output directory &quot;$(saved-output)</span><span class="string">&quot;))</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">PHONY += <span class="variable">$(MAKECMDGOALS)</span> sub-make</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">$(filter-out _all sub-make <span class="variable">$(CURDIR)</span>/Makefile, <span class="variable">$(MAKECMDGOALS)</span>) _all: sub-make</span></span><br><span class="line"><span class="string">	@:</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">sub-make: FORCE</span></span><br><span class="line"><span class="string">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> -C <span class="variable">$(KBUILD_OUTPUT)</span> KBUILD_SRC=<span class="variable">$(CURDIR)</span> \</span></span><br><span class="line"><span class="string">	-f <span class="variable">$(CURDIR)</span>/Makefile $(filter-out _all sub-make,<span class="variable">$(MAKECMDGOALS)</span>)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"># Leave processing to above invocation of make</span></span><br><span class="line"><span class="string">skip-makefile := 1</span></span><br><span class="line"><span class="string">endif # ifneq (<span class="variable">$(KBUILD_OUTPUT)</span>,)</span></span><br><span class="line"><span class="string">endif # ifeq (<span class="variable">$(KBUILD_SRC)</span>,)</span></span><br></pre></td></tr></table></figure>

<h3 id="4-2-O参数来源判断"><a href="#4-2-O参数来源判断" class="headerlink" title="4.2 O参数来源判断"></a><font size=3>4.2 O参数来源判断</font></h3><p><a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L122">Makefile</a>文件判断O参数来源的代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="string">&quot;$(origin O)&quot;</span>, <span class="string">&quot;command line&quot;</span>)</span><br><span class="line">  KBUILD_OUTPUT := <span class="variable">$(O)</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>行判断“O”是否来自于命令行，如果来自命令行的话条件成立，KBUILD_OUTPUT 就为$(O)，因此变量 KBUILD_OUTPUT 就是输出目录。</p>
<h3 id="4-3-创建KBUILD-OUTPUT目录"><a href="#4-3-创建KBUILD-OUTPUT目录" class="headerlink" title="4.3 创建KBUILD_OUTPUT目录"></a><font size=3>4.3 创建KBUILD_OUTPUT目录</font></h3><p>还需要判断一下这个KBUILD_OUTPUT目录是否存在，不存在的话，会进行创建，<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L136">Makefile </a>中对应的代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">saved-output := <span class="variable">$(KBUILD_OUTPUT)</span></span><br><span class="line">KBUILD_OUTPUT := <span class="variable">$(<span class="built_in">shell</span> mkdir -p <span class="variable">$(KBUILD_OUTPUT)</span> &amp;&amp; cd <span class="variable">$(KBUILD_OUTPUT)</span> \</span></span><br><span class="line"><span class="variable">								&amp;&amp; /bin/pwd)</span></span><br><span class="line"><span class="variable">$(<span class="built_in">if</span> <span class="variable">$(KBUILD_OUTPUT)</span>,, \</span></span><br><span class="line"><span class="variable">     $(<span class="built_in">error</span> failed to create output directory &quot;$(saved-output)</span><span class="string">&quot;))</span></span><br></pre></td></tr></table></figure>

<p>这里相当于将KBUILD_OUTPUT重新赋值了一下，从相对路径变为绝对路径。经过这里之后，一个不存在的输出目录就被创建好了。</p>
<h2 id="5-代码检查"><a href="#5-代码检查" class="headerlink" title="5. 代码检查"></a><font size=3>5. 代码检查</font></h2><h3 id="5-1-代码检查控制命令"><a href="#5-1-代码检查控制命令" class="headerlink" title="5.1 代码检查控制命令"></a><font size=3>5.1 代码检查控制命令</font></h3><p>uboot 支持代码检查，命令如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make C=1 # 使能代码检查，检查那些需要重新编译的文件。</span><br><span class="line">make C=2 # 用于检查所有的源码文件</span><br></pre></td></tr></table></figure>

<h3 id="5-2-KBUILD-CHECKSRC"><a href="#5-2-KBUILD-CHECKSRC" class="headerlink" title="5.2 KBUILD_CHECKSRC"></a><font size=3>5.2 KBUILD_CHECKSRC</font></h3><p>顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L167">Makefile</a> 中的代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Call a source code checker (by default, &quot;sparse&quot;) as part of the</span></span><br><span class="line"><span class="comment"># C compilation.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Use &#x27;make C=1&#x27; to enable checking of only re-compiled files.</span></span><br><span class="line"><span class="comment"># Use &#x27;make C=2&#x27; to enable checking of *all* source files, regardless</span></span><br><span class="line"><span class="comment"># of whether they are re-compiled or not.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># See the file &quot;doc/sparse.txt&quot; for more details, including</span></span><br><span class="line"><span class="comment"># where to get the &quot;sparse&quot; utility.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="string">&quot;$(origin C)&quot;</span>, <span class="string">&quot;command line&quot;</span>)</span><br><span class="line">  KBUILD_CHECKSRC = <span class="variable">$(C)</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">ifndef</span> KBUILD_CHECKSRC</span><br><span class="line">  KBUILD_CHECKSRC = 0</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>和前面一样，判断一下 C 是否来源于命令行，如果 C 来源于命令行，那就将 C 赋值给变量 KBUILD_CHECKSRC，如果命令行没有 C 的话 KBUILD_CHECKSRC 就为 0。</p>
<h2 id="6-模块编译"><a href="#6-模块编译" class="headerlink" title="6. 模块编译"></a><font size=3>6. 模块编译</font></h2><h3 id="6-1-模块编译命令"><a href="#6-1-模块编译命令" class="headerlink" title="6.1 模块编译命令"></a><font size=3>6.1 模块编译命令</font></h3><p>在 uboot 中允许单独编译某个模块，使用以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make M=dir</span><br><span class="line">make SUBDIRS=dir # 旧语法是这样的，也是支持的。</span><br></pre></td></tr></table></figure>

<h3 id="6-2-KBUILD-EXTMOD"><a href="#6-2-KBUILD-EXTMOD" class="headerlink" title="6.2 KBUILD_EXTMOD"></a><font size=3>6.2 KBUILD_EXTMOD</font></h3><p>我们看一下 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L181">Makefile</a> 中对这个参数的定义：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Use make M=dir to specify directory of external module to build</span></span><br><span class="line"><span class="comment"># Old syntax make ... SUBDIRS=$PWD is still supported</span></span><br><span class="line"><span class="comment"># Setting the environment variable KBUILD_EXTMOD take precedence</span></span><br><span class="line"><span class="keyword">ifdef</span> SUBDIRS</span><br><span class="line">  KBUILD_EXTMOD ?= <span class="variable">$(SUBDIRS)</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="string">&quot;$(origin M)&quot;</span>, <span class="string">&quot;command line&quot;</span>)</span><br><span class="line">  KBUILD_EXTMOD := <span class="variable">$(M)</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>首先判断是否定义了 SUBDIRS ， 如果定义了 SUBDIRS ， 变量 KBUILD_EXTMOD&#x3D;SUBDIRS，这里是为了支持老语法“make SUBIDRS&#x3D;dir” 。</p>
<p>接着后面是判断是否在命令行定义了 M，如果定义了的话 KBUILD_EXTMOD&#x3D;$(M)。</p>
<h3 id="6-3-编译目标"><a href="#6-3-编译目标" class="headerlink" title="6.3 编译目标"></a><font size=3>6.3 编译目标</font></h3><p>接着是根据上面的KBUILD_EXTMOD是否为空来确定编译目标，我们看一下 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L192">Makefile</a> 文件：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># If building an external module we do not care about the all: rule</span></span><br><span class="line"><span class="comment"># but instead _all depend on modules</span></span><br><span class="line">PHONY += all</span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_EXTMOD)</span>,)</span><br><span class="line"><span class="section">_all: all</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="section">_all: modules</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>判断 KBUILD_EXTMOD 时为空，如果为空的话目标_all 依赖 all，因此要先编译出 all。否则的话默认目标_all 依赖 modules，要先编译出 modules，也就是编译模块。一般情况 下我们不会在 uboot 中编译模块，所以此处会编译 all 这个目标。</p>
<h2 id="7-VPATH的配置"><a href="#7-VPATH的配置" class="headerlink" title="7. VPATH的配置"></a><font size=3>7. VPATH的配置</font></h2><p>看一下 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L201">Makefile</a> 这一部分：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_SRC)</span>,)</span><br><span class="line">        <span class="comment"># building in the source tree</span></span><br><span class="line">        srctree := .</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">        <span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_SRC)</span>/,<span class="variable">$(<span class="built_in">dir</span> <span class="variable">$(CURDIR)</span>)</span>)</span><br><span class="line">                <span class="comment"># building in a subdirectory of the source tree</span></span><br><span class="line">                srctree := ..</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">                srctree := <span class="variable">$(KBUILD_SRC)</span></span><br><span class="line">        <span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line">objtree		:= .</span><br><span class="line">src		:= <span class="variable">$(srctree)</span></span><br><span class="line">obj		:= <span class="variable">$(objtree)</span></span><br><span class="line"></span><br><span class="line">VPATH		:= <span class="variable">$(srctree)</span><span class="variable">$(<span class="built_in">if</span> <span class="variable">$(KBUILD_EXTMOD)</span>,:<span class="variable">$(KBUILD_EXTMOD)</span>)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> srctree objtree VPATH</span><br></pre></td></tr></table></figure>

<p>第 1~11 行判断 KBUILD_SRC 是否为空，如果为空的话就设置变量 srctree 为当前目录，即 srctree 为“.”，一般不设置 KBUILD_SRC。 </p>
<p>第 12 行设置变量 objtree 为当前目录。 </p>
<p>第 13~14 行分别设置变量 src 和 obj，根据前面的变量的值，这里都为当前目录。</p>
<p>第 16 行设置 VPATH。 这里会KBUILD_EXTMOD是否为空，要是非空，这里就会加入KBUILD_EXTMOD路径。也就是要编译的模块的路径。</p>
<p>第 18 行导出变量 scrtree、objtree 和 VPATH。</p>
<h2 id="8-编译平台"><a href="#8-编译平台" class="headerlink" title="8. 编译平台"></a><font size=3>8. 编译平台</font></h2><h3 id="8-1-主机架构-HOSTARCH"><a href="#8-1-主机架构-HOSTARCH" class="headerlink" title="8.1 主机架构 HOSTARCH"></a><font size=3>8.1 主机架构 HOSTARCH</font></h3><p>HOSTARCH在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L225">Makefile</a>中定义如下：</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">HOSTARCH := $(shell uname -m | \</span><br><span class="line">	sed -e s/i.<span class="number">86</span>/x86/ \</span><br><span class="line">	    -e s/sun4u/sparc64/ \</span><br><span class="line">	    -e s/arm.*/arm/ \</span><br><span class="line">	    -e s/sa110/arm/ \</span><br><span class="line">	    -e s/ppc64/powerpc/ \</span><br><span class="line">	    -e s/ppc/powerpc/ \</span><br><span class="line">	    -e s/macppc/powerpc/\</span><br><span class="line">	    -e s/sh.*/sh/)</span><br></pre></td></tr></table></figure>

<p>变量 HOSTARCH，用于保存主机架构，这里调用 shell 命令“uname -m”获取架构名称：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$  uname -m</span><br><span class="line">x86_64</span><br></pre></td></tr></table></figure>

<p>可以看出当前ubuntu主机架构为“x86_64”，shell 中的“|”表示管道，意思是将 左边的输出作为右边的输入，sed -e 是替换命令，“sed -e s&#x2F;i.86&#x2F;x86&#x2F;”表示将管道输入的字符串 中的“i.86”替换为“x86”，其他的“sed -e s”命令同理。对于我现在运行的ubuntu系统而言，HOSTARCH&#x3D;x86_64。</p>
<h3 id="8-2-主机操作系统-HOSTOS"><a href="#8-2-主机操作系统-HOSTOS" class="headerlink" title="8.2 主机操作系统 HOSTOS"></a><font size=3>8.2 主机操作系统 HOSTOS</font></h3><p> HOSTOS在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L235">Makefile</a> 中定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">HOSTOS := <span class="variable">$(<span class="built_in">shell</span> uname -s | tr &#x27;[:upper:]&#x27; &#x27;[:lower:]&#x27; | \</span></span><br><span class="line"><span class="variable">	    sed -e &#x27;s/\(cygwin\)</span>.*/cygwin/&#x27;)</span><br></pre></td></tr></table></figure>

<p>变量 HOSTOS，此变量用于保存主机 OS 的值，先使用 shell 命令“uname -s”来获取主机 OS，结果下所示：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$  uname -s</span><br><span class="line">Linux</span><br></pre></td></tr></table></figure>

<p>可以看出此时的主机 OS 为“Linux”，使用管道将“Linux”作为后面“ tr ‘[:upper:]‘  ‘[:lower:]‘ ”的输入，“ tr ‘[:upper:]‘ ‘[:lower:]‘ ”表示将所有的大写字母替换为小写字母，因此得到 “ linux ”。最后同样使用管道，将“ linux ”作为“ sed -e ‘s&#x2F;(cygwin).*&#x2F;cygwin&#x2F;‘ ”的输入，用于将 cygwin.*替换为 cygwin。因此，现在在这里HOSTOS&#x3D;linux。</p>
<h3 id="8-3-导出HOSTARCH和HOSTOS"><a href="#8-3-导出HOSTARCH和HOSTOS" class="headerlink" title="8.3 导出HOSTARCH和HOSTOS"></a><font size=3>8.3 导出HOSTARCH和HOSTOS</font></h3><p>接着导出这两个变量，在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L238">Makefile</a>中定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span>	HOSTARCH HOSTOS</span><br></pre></td></tr></table></figure>

<h3 id="8-4-目标架构和编译器"><a href="#8-4-目标架构和编译器" class="headerlink" title="8.4 目标架构和编译器"></a><font size=3>8.4 目标架构和编译器</font></h3><h4 id="8-4-1-设置命令"><a href="#8-4-1-设置命令" class="headerlink" title="8.4.1 设置命令"></a><font size=3>8.4.1 设置命令</font></h4><p>编译 uboot 的时候需要设置目标板架构和交叉编译器，我们一般在使用make命令的时候传入：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-</span><br></pre></td></tr></table></figure>

<p>这个命令就是用于设置 ARCH 和CROSS_COMPILE。</p>
<h4 id="8-4-2-ARCH与CROSS-COMPILE"><a href="#8-4-2-ARCH与CROSS-COMPILE" class="headerlink" title="8.4.2 ARCH与CROSS_COMPILE"></a><font size=3>8.4.2 ARCH与CROSS_COMPILE</font></h4><p>在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L243">Makefile</a> 中代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(HOSTARCH)</span>,<span class="variable">$(ARCH)</span>)</span><br><span class="line">CROSS_COMPILE ?=</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>这里判断 HOSTARCH 和 ARCH 这两个变量是否相等，前面我们知道主机架构(变量 HOSTARCH)是 x86_64，ARCH就是通过make命令传入，要是没有传入，那ARCH就为空，我们编译的是 ARM 版本 uboot，肯定不相等，所以 CROSS_COMPILE&#x3D; arm-linux-gnueabihf-。当然，要是我们在ARM开发板装了GCC，这里就不需要前缀了，因为开发板上装的GCC一定就是ARM版本的，可以直接本地编译，不需要交叉编译。</p>
<p>可以看到，每次编译 uboot 的时候都要在 make 命令后面设置 ARCH 和 CROSS_COMPILE，使用起来很麻烦（当然，写shell脚本调用Makefile的除外），我们完全可以直接修改顶层 Makefile，在里面加入 ARCH 和 CROSS_COMPILE 的定义，如下所示：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ARCH          ?= arm</span><br><span class="line">CROSS_COMPILE ?= arm-linux-gnueabihf-</span><br></pre></td></tr></table></figure>

<p>这样直接在顶层 Makefile 里面定义 ARCH 和 CROSS_COMPILE，这样就不用每次编译的时候都要在 make 命令后面定义 ARCH 和 CROSS_COMPILE，直接一个make就可以了。</p>
<h2 id="9-配置文件"><a href="#9-配置文件" class="headerlink" title="9. 配置文件"></a><font size=3>9. 配置文件</font></h2><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">KCONFIG_CONFIG	?= .config</span><br><span class="line"><span class="keyword">export</span> KCONFIG_CONFIG</span><br></pre></td></tr></table></figure>

<p>uboot 是可以配置的，这里设置配置文件为 .config。.config 文件默认是没有的，需要使用命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make xxx_defconfig</span><br></pre></td></tr></table></figure>

<p>对 uboot 进行配置，配置完成以后就会在 uboot 根目录下生成 .config。默认情况下.config 和 xxx_defconfig 内容是一样的，因为 .config 就是从 xxx_defconfig 复制过来的。如果后续自行调整 了 uboot 的一些配置参数，那么这些新的配置参数就添加到了.config 中，而不是 xxx_defconfig。 相当于 xxx_defconfig 只是一些初始配置，而 .config 里面的才是实时有效的配置。我们在图形配置界面进行的各种配置也会被写入到这个 .config 文件中。</p>
<h2 id="10-通用定义"><a href="#10-通用定义" class="headerlink" title="10. 通用定义"></a><font size=3>10. 通用定义</font></h2><h3 id="10-1-Kbuild-include"><a href="#10-1-Kbuild-include" class="headerlink" title="10.1 Kbuild.include"></a><font size=3>10.1 Kbuild.include</font></h3><p>这里还会有一些通用的定义在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Kbuild.include">scripts&#x2F;Kbuild.include</a> 文件中：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">####</span><br><span class="line"># kbuild: Generic definitions</span><br><span class="line"></span><br><span class="line"># Convenient variables</span><br><span class="line">comma   := ,</span><br><span class="line">quote   := &quot;</span><br><span class="line">squote  := &#x27;</span><br><span class="line">empty   :=</span><br><span class="line">space   := $(empty) $(empty)</span><br><span class="line">pound := \#</span><br><span class="line"></span><br><span class="line">###</span><br><span class="line"># Name of target with a &#x27;.&#x27; as filename prefix. foo/bar.o =&gt; foo/.bar.o</span><br><span class="line">dot-target = $(dir $@).$(notdir $@)</span><br><span class="line"></span><br><span class="line">###</span><br><span class="line"># The temporary file to save gcc -MD generated dependencies must not</span><br><span class="line"># contain a comma</span><br><span class="line">depfile = $(subst $(comma),_,$(dot-target).d)</span><br></pre></td></tr></table></figure>

<h3 id="10-2-怎么被包含到Makefile中？"><a href="#10-2-怎么被包含到Makefile中？" class="headerlink" title="10.2 怎么被包含到Makefile中？"></a><font size=3>10.2 怎么被包含到Makefile中？</font></h3><p>在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L345">Makefile</a>中调用的代码：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># We need some generic definitions (do not try to remake the file).</span></span><br><span class="line"><span class="section">scripts/Kbuild.include: ;</span></span><br><span class="line"><span class="keyword">include</span> scripts/Kbuild.<span class="keyword">include</span></span><br></pre></td></tr></table></figure>

<p>在 uboot 的编译过程中会用到 scripts&#x2F;Kbuild.include 中的这些变量，后面用到的时候再分析。</p>
<h2 id="11-相关变量"><a href="#11-相关变量" class="headerlink" title="11. 相关变量"></a><font size=3>11. 相关变量</font></h2><h3 id="11-1-交叉编译工具变量"><a href="#11-1-交叉编译工具变量" class="headerlink" title="11.1 交叉编译工具变量"></a><font size=3>11.1 交叉编译工具变量</font></h3><p>上面我们只是设置了 CROSS_COMPILE 的名字，但是交叉编译器其他的工具还没有设置，顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L347">Makefile</a> 中相关代码如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">AS		= <span class="variable">$(CROSS_COMPILE)</span>as</span><br><span class="line"><span class="comment"># Always use GNU ld</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">shell</span> <span class="variable">$(CROSS_COMPILE)</span>ld.bfd -v 2&gt; /dev/null)</span>,)</span><br><span class="line">LD		= <span class="variable">$(CROSS_COMPILE)</span>ld.bfd</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">LD		= <span class="variable">$(CROSS_COMPILE)</span>ld</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line">CC		= <span class="variable">$(CROSS_COMPILE)</span>gcc</span><br><span class="line">CPP		= <span class="variable">$(CC)</span> -E</span><br><span class="line">AR		= <span class="variable">$(CROSS_COMPILE)</span>ar</span><br><span class="line">NM		= <span class="variable">$(CROSS_COMPILE)</span>nm</span><br><span class="line">LDR		= <span class="variable">$(CROSS_COMPILE)</span>ldr</span><br><span class="line">STRIP		= <span class="variable">$(CROSS_COMPILE)</span>strip</span><br><span class="line">OBJCOPY		= <span class="variable">$(CROSS_COMPILE)</span>objcopy</span><br><span class="line">OBJDUMP		= <span class="variable">$(CROSS_COMPILE)</span>objdump</span><br><span class="line">LEX		= flex</span><br><span class="line">YACC		= bison</span><br><span class="line">AWK		= awk</span><br><span class="line">PERL		= perl</span><br><span class="line">PYTHON		?= python</span><br><span class="line">PYTHON2		= python2</span><br><span class="line">PYTHON3		= python3</span><br><span class="line">DTC		?= <span class="variable">$(objtree)</span>/scripts/dtc/dtc</span><br></pre></td></tr></table></figure>

<h3 id="11-2-编译选项"><a href="#11-2-编译选项" class="headerlink" title="11.2 编译选项"></a><font size=3>11.2 编译选项</font></h3><p>我们编译的时候还有一些选项的定义，这些在顶层的 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L374">Makefile</a>中也有定义，例如这里就有一些宏和标志：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \</span><br><span class="line">		  -Wbitwise -Wno-return-void -D__CHECK_ENDIAN__ <span class="variable">$(CF)</span></span><br><span class="line"></span><br><span class="line">KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__</span><br><span class="line"></span><br><span class="line">KBUILD_CFLAGS   := -Wall -Wstrict-prototypes \</span><br><span class="line">		   -Wno-format-security \</span><br><span class="line">		   -fno-builtin -ffreestanding <span class="variable">$(CSTD_FLAG)</span></span><br><span class="line">KBUILD_CFLAGS	+= -fshort-wchar -fno-strict-aliasing</span><br><span class="line">KBUILD_AFLAGS   := -D__ASSEMBLY__</span><br></pre></td></tr></table></figure>

<h3 id="11-3-变量导出"><a href="#11-3-变量导出" class="headerlink" title="11.3 变量导出"></a><font size=3>11.3 变量导出</font></h3><p>接下来在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L393">Makefile</a> 会导出很多变量：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION</span><br><span class="line"><span class="keyword">export</span> ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR</span><br><span class="line"><span class="keyword">export</span> CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC</span><br><span class="line"><span class="keyword">export</span> CPP AR NM LDR STRIP OBJCOPY OBJDUMP</span><br><span class="line"><span class="keyword">export</span> MAKE LEX YACC AWK PERL PYTHON PYTHON2 PYTHON3</span><br><span class="line"><span class="keyword">export</span> HOSTCXX HOSTCXXFLAGS CHECK CHECKFLAGS DTC DTC_FLAGS</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS</span><br><span class="line"><span class="keyword">export</span> KBUILD_CFLAGS KBUILD_AFLAGS</span><br><span class="line"></span><br><span class="line"><span class="comment"># When compiling out-of-tree modules, put MODVERDIR in the module</span></span><br><span class="line"><span class="comment"># tree rather than in the kernel tree. The kernel tree might</span></span><br><span class="line"><span class="comment"># even be read-only.</span></span><br><span class="line"><span class="keyword">export</span> MODVERDIR := <span class="variable">$(<span class="built_in">if</span> <span class="variable">$(KBUILD_EXTMOD)</span>,$(<span class="built_in">firstword</span> <span class="variable">$(KBUILD_EXTMOD)</span>)</span>/).tmp_versions</span><br><span class="line"></span><br><span class="line"><span class="comment"># Files to ignore in find ... statements</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o    \</span><br><span class="line">			  -name CVS -o -name .pc -o -name .hg -o -name .git \) \</span><br><span class="line">			  -prune -o</span><br><span class="line"><span class="keyword">export</span> RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \</span><br><span class="line">			 --exclude CVS --exclude .pc --exclude .hg --exclude .git</span><br></pre></td></tr></table></figure>

<p>这些变量中大部分都已经在前面定义了，我们重点来看一下下面这几个变量：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR</span><br></pre></td></tr></table></figure>

<p>这 7 个变量在顶层 Makefile 是找不到的，说明这 7 个变量是在其他文件里面定义的。先来看一下这 7 个变量都是什么内容，在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L415">Makefile</a> 中导出变量结束的位置输入如图所示的内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ......</span></span><br><span class="line"><span class="keyword">export</span> RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \</span><br><span class="line">			 --exclude CVS --exclude .pc --exclude .hg --exclude .git</span><br><span class="line"></span><br><span class="line"><span class="section">my_test:</span></span><br><span class="line">	@echo <span class="string">&quot;ARCH&quot;</span>=<span class="variable">$(ARCH)</span> </span><br><span class="line">	@echo <span class="string">&quot;CPU&quot;</span>=<span class="variable">$(CPU)</span> </span><br><span class="line">	@echo <span class="string">&quot;BOARD&quot;</span>=<span class="variable">$(BOARD)</span> </span><br><span class="line">	@echo <span class="string">&quot;VENDOR&quot;</span>=<span class="variable">$(VENDOR)</span> </span><br><span class="line">	@echo <span class="string">&quot;SOC&quot;</span>=<span class="variable">$(SOC)</span> </span><br><span class="line">	@echo <span class="string">&quot;CPUDIR&quot;</span>=<span class="variable">$(CPUDIR)</span> </span><br><span class="line">	@echo <span class="string">&quot;BOARDDIR&quot;</span>=<span class="variable">$(BOARDDIR)</span></span><br></pre></td></tr></table></figure>

<p>然后执行以下命令看一下打印信息：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$  make -s ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- my_test -j16</span><br><span class="line">ARCH=arm</span><br><span class="line">CPU=armv7</span><br><span class="line">BOARD=mx6ullevk</span><br><span class="line">VENDOR=freescale</span><br><span class="line">SOC=mx6</span><br><span class="line">CPUDIR=arch/arm/cpu/armv7</span><br><span class="line">BOARDDIR=freescale/mx6ullevk</span><br></pre></td></tr></table></figure>

<p>可以看到这 7 个变量的值，这 7 个变量是从哪里来的呢？在 uboot 根目录下有个文件叫做 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/config.mk">config.mk</a>，这 7 个变量就是在  <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/config.mk">config.mk</a> 里面定义的，打开  <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/config.mk">config.mk</a> 内容如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ......</span></span><br><span class="line"><span class="comment"># clear VENDOR for tcsh</span></span><br><span class="line">VENDOR :=</span><br><span class="line"><span class="comment">#########################################################################</span></span><br><span class="line"></span><br><span class="line">ARCH := $(CONFIG_SYS_ARCH:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line">CPU := $(CONFIG_SYS_CPU:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line"><span class="keyword">ifdef</span> CONFIG_SPL_BUILD</span><br><span class="line"><span class="keyword">ifdef</span> CONFIG_TEGRA</span><br><span class="line">CPU := arm720t</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line">BOARD := $(CONFIG_SYS_BOARD:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(CONFIG_SYS_VENDOR)</span>,)</span><br><span class="line">VENDOR := $(CONFIG_SYS_VENDOR:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(CONFIG_SYS_SOC)</span>,)</span><br><span class="line">SOC := $(CONFIG_SYS_SOC:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="comment"># ......</span></span><br><span class="line">CPUDIR=arch/<span class="variable">$(ARCH)</span>/cpu<span class="variable">$(<span class="built_in">if</span> <span class="variable">$(CPU)</span>,/<span class="variable">$(CPU)</span>,)</span></span><br><span class="line"><span class="comment"># ......</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(BOARD)</span>,)</span><br><span class="line"><span class="keyword">ifdef</span>	VENDOR</span><br><span class="line">BOARDDIR = <span class="variable">$(VENDOR)</span>/<span class="variable">$(BOARD)</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">BOARDDIR = <span class="variable">$(BOARD)</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="comment"># ......</span></span><br></pre></td></tr></table></figure>

<p>接下来需要找到 CONFIG_SYS_ARCH、 CONFIG_SYS_CPU、 CONFIG_SYS_BOARD、CONFIG_SYS_VENDOR 和 CONFIG_SYS_SOC 这 5 个变量的值。这 5 个变量在 uboot 根目录下的  <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/.config">.config</a> 文件（这个文件需要执行配置命令后才会生成）中有定义，，可以打开看一下，搜索一下这个几个变量，会发现他们在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/.config#L19">.config </a> 文件中定义如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">CONFIG_SYS_ARCH=&quot;arm&quot;</span><br><span class="line">CONFIG_SYS_CPU=&quot;armv7&quot;</span><br><span class="line">CONFIG_SYS_SOC=&quot;mx6&quot;</span><br><span class="line">CONFIG_SYS_VENDOR=&quot;freescale&quot;</span><br><span class="line">CONFIG_SYS_BOARD=&quot;mx6ull_alpha_emmc&quot;</span><br><span class="line">CONFIG_SYS_CONFIG_NAME=&quot;mx6ull_alpha_emmc&quot;</span><br></pre></td></tr></table></figure>

<p>主要是这里我是用的自己移植的板子，所以这些名字什么都不太一样，不过用nxp evk评估板的默认配置文件的话会是对应的。所以就有：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">ARCH = arm</span><br><span class="line">CPU = armv7</span><br><span class="line">BOARD = mx6ullevk</span><br><span class="line">VENDOR = freescale</span><br><span class="line">SOC = mx6</span><br><span class="line">CPUDIR = arch/arm/cpu/armv7</span><br><span class="line">BOARDDIR = freescale/mx6ullevk</span><br></pre></td></tr></table></figure>

<p>会发现和上面的打印信息是一样的。再来分析 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/config.mk">config.mk</a> ，就会发现在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/config.mk">config.mk</a> 中读取的文件有 :</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">arch/arm/config.mk</span><br><span class="line">arch/arm/cpu/armv7/config.mk</span><br><span class="line">arch/arm/cpu/armv7/mx6/config.mk (此文件不存在)</span><br><span class="line">board/ freescale/mx6ullevk/config.mk (此文件不存在)</span><br></pre></td></tr></table></figure>

<h1 id="二、Makefile过程分析"><a href="#二、Makefile过程分析" class="headerlink" title="二、Makefile过程分析"></a><font size=3>二、Makefile过程分析</font></h1><h2 id="1-make-xxx-defconfig"><a href="#1-make-xxx-defconfig" class="headerlink" title="1.  make xxx_defconfig"></a><font size=3>1.  make xxx_defconfig</font></h2><p>在编译 uboot 之前要使用“make xxx_defconfig”命令来配置 uboot，那么这个配置过程是如何运行的呢？接下来就来了解一下吧。这个我们从这里开始：<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L439">Makefile · 苏木&#x2F;u-boot - 码云 - 开源中国</a></p>
<h3 id="1-1-版本与时间"><a href="#1-1-版本与时间" class="headerlink" title="1.1 版本与时间"></a><font size=3>1.1 版本与时间</font></h3><h4 id="1-1-1-version-h"><a href="#1-1-1-version-h" class="headerlink" title="1.1.1 version_h"></a><font size=3>1.1.1 version_h</font></h4><p>先来看一些这个变量，它在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L447">Makefile</a>中定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">version_h := <span class="keyword">include</span>/generated/version_autogenerated.h</span><br></pre></td></tr></table></figure>

<p>这个变量保存版本号文件，此文件是自动生成的。文件 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/include/generated/version_autogenerated.h">include&#x2F;generated&#x2F;version_autogenerated.h</a> （编译后才会生成）内容如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> PLAIN_VERSION <span class="string">&quot;2019.04-gf32bcf5b&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_VERSION <span class="string">&quot;U-Boot &quot;</span> PLAIN_VERSION</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> CC_VERSION_STRING <span class="string">&quot;arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> LD_VERSION_STRING <span class="string">&quot;GNU ld (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 2.32.0.20190321&quot;</span></span></span><br></pre></td></tr></table></figure>

<h4 id="1-1-2-timestamp-h"><a href="#1-1-2-timestamp-h" class="headerlink" title="1.1.2 timestamp_h"></a><font size=3>1.1.2 timestamp_h</font></h4><p>变量 timestamp_h在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L448">Makefile</a> 中定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">timestamp_h := <span class="keyword">include</span>/generated/timestamp_autogenerated.h</span><br></pre></td></tr></table></figure>

<p>这个变量保存时间戳文件，此文件也是编译自动生成的。文件 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/include/generated/timestamp_autogenerated.h">include&#x2F;generated&#x2F;timestamp_autogenerated.h</a> 内容如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_DATE <span class="string">&quot;Nov 19 2024&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_TIME <span class="string">&quot;21:45:10&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_TZ <span class="string">&quot;+0800&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_DMI_DATE <span class="string">&quot;11/19/2024&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> U_BOOT_BUILD_DATE 0x20241119</span></span><br></pre></td></tr></table></figure>

<h3 id="1-2-三个变量"><a href="#1-2-三个变量" class="headerlink" title="1.2 三个变量"></a><font size=3>1.2 三个变量</font></h3><p>接下来看几个变量，定义在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L451">Makefile</a>：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">no-dot-config-targets := clean clobber mrproper distclean \</span><br><span class="line">			 help %docs check% coccicheck \</span><br><span class="line">			 ubootversion backup tests check qcheck</span><br><span class="line"></span><br><span class="line">config-targets := 0</span><br><span class="line">mixed-targets  := 0</span><br><span class="line">dot-config     := 1</span><br><span class="line"></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> $(no-dot-config-targets)</span>, <span class="variable">$(MAKECMDGOALS)</span>),)</span><br><span class="line">	<span class="keyword">ifeq</span> (<span class="variable">$(<span class="built_in">filter</span>-out $(no-dot-config-targets)</span>, <span class="variable">$(MAKECMDGOALS)</span>),)</span><br><span class="line">		dot-config := 0</span><br><span class="line">	<span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_EXTMOD)</span>,)</span><br><span class="line">        <span class="keyword">ifneq</span> (<span class="variable">$(<span class="built_in">filter</span> config %config,<span class="variable">$(MAKECMDGOALS)</span>)</span>,)</span><br><span class="line">                config-targets := 1</span><br><span class="line">                <span class="keyword">ifneq</span> (<span class="variable">$(words <span class="variable">$(MAKECMDGOALS)</span>)</span>,1)</span><br><span class="line">                        mixed-targets := 1</span><br><span class="line">                <span class="keyword">endif</span></span><br><span class="line">        <span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>第 1 行定义了变量 no-dot-config-targets。</p>
<p>第 5 行定义了变量 config-targets，初始值为 0。 </p>
<p>第 6 行定义了变量 mixed-targets，初始值为 0。</p>
<p>第 7 行定义了变量 dot-config，初始值为 1。</p>
<p>第 9 行将 MAKECMDGOALS 中不符合 no-dot-config-targets 的部分过滤掉，剩下的如果不为空的话条件就成立。MAKECMDGOALS 是 make 的一个环境变量，这个变量会保存我们所指 定的终极目标列表，比如执行“make mx6ull_14x14_evk_defconfig”，那么 MAKECMDGOALS 就为 mx6ull_14x14_evk_defconfig。很明显过滤后为空，所以条件不成立，变量 dot-config 依 旧为 1。</p>
<p>第 15 行判断KBUILD_EXTMOD是否为空，如果KBUILD_EXTMOD为空的话条件成立， 经过前面的分析，我们知道 KBUILD_EXTMOD 为空，所以条件成立。</p>
<p>第 16 行将 MAKECMDGOALS 中不符合“config”和“%config”的部分过滤掉，如果剩 下的部分不为空条件就成立，MAKECMDGOALS &#x3D; mx6ull_14x14_evk_defconfig，所以此处条件成立，变量 config-targets&#x3D;1。</p>
<p>第 18 行统计 MAKECMDGOALS 中的单词个数，如果不为 1 的话条件成立。此处调用 Makefile 中的 words 函数来统计单词个数，words 函数格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(words &lt;text&gt;)</span></span><br></pre></td></tr></table></figure>

<p>MAKECMDGOALS 的单词个数是 1 个，所以条件不成立，mixed-targets 继续为 0。</p>
<p>综上所述，这些变量值如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">config-targets = 1</span><br><span class="line">mixed-targets = 0</span><br><span class="line">dot-config = 1</span><br></pre></td></tr></table></figure>

<h3 id="1-3-三个变量的使用"><a href="#1-3-三个变量的使用" class="headerlink" title="1.3 三个变量的使用"></a><font size=3>1.3 三个变量的使用</font></h3><p>上面确定了那三个变量的值，我们继续往下看 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L474">Makefile</a> ：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> ($(mixed-targets),1)</span><br><span class="line"><span class="comment"># (1)......</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="comment"># (2)......</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>如果变量 mixed-targets 为 1 的话条件成立,这里显然不成立了，所以会走2)这里，(2)这里在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L490">Makefile</a> 中是：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> ($(config-targets),1)</span><br><span class="line"><span class="comment"># (2.1)......</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="comment"># (2.2)......</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>如果变量 config-targets 为 1 的话条件成立，很明显，条件成立，执行这个（2.1）分支。这个（2.1）在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L492">Makefile</a> 中的代码，我们下面接着分析。</p>
<h3 id="1-4-config"><a href="#1-4-config" class="headerlink" title="1.4 %config"></a><font size=3>1.4 %config</font></h3><p>我们来看一下上面（2.1）在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L492">Makefile</a> 中的代码：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># *config targets only - make sure prerequisites are updated, and descend</span></span><br><span class="line"><span class="comment"># in scripts/kconfig to make the *config target</span></span><br><span class="line"></span><br><span class="line">KBUILD_DEFCONFIG := sandbox_defconfig</span><br><span class="line"><span class="keyword">export</span> KBUILD_DEFCONFIG KBUILD_KCONFIG</span><br><span class="line"></span><br><span class="line"><span class="section">config: scripts_basic outputmakefile FORCE</span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> <span class="variable">$(build)</span>=scripts/kconfig <span class="variable">$@</span></span><br><span class="line"></span><br><span class="line"><span class="section">%config: scripts_basic outputmakefile FORCE</span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> <span class="variable">$(build)</span>=scripts/kconfig <span class="variable">$@</span></span><br></pre></td></tr></table></figure>

<p>第 7 行，没有目标与之匹配，所以不执行。</p>
<p>第 10 行，有目标与之匹配，当输入“make xxx_defconfig”的时候就会匹配到%config 目标，目标“%config”依赖于 scripts_basic、 outputmakefile 和 FORCE。</p>
<h4 id="1-4-1-FORCE"><a href="#1-4-1-FORCE" class="headerlink" title="1.4.1 FORCE"></a><font size=3>1.4.1 FORCE</font></h4><p> FORCE 在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1978">Makefile</a>中定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">PHONY += FORCE</span><br><span class="line"><span class="section">FORCE:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Declare the contents of the .PHONY variable as phony.  We keep that</span></span><br><span class="line"><span class="comment"># information in a variable so we can use it in if_changed and friends.</span></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: $(PHONY)</span></span><br></pre></td></tr></table></figure>

<p>可以看出 FORCE 是没有规则和依赖的，所以每次都会重新生成 FORCE。当 FORCE 作为 其他目标的依赖时，由于 FORCE 总是被更新过的，因此依赖所在的规则总是会执行的。</p>
<h4 id="1-4-2-scripts-basic"><a href="#1-4-2-scripts-basic" class="headerlink" title="1.4.2 scripts_basic"></a><font size=3>1.4.2 scripts_basic</font></h4><p>依赖 scripts_basic在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L419">Makefile</a>中定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Basic helpers built in scripts/</span></span><br><span class="line">PHONY += scripts_basic</span><br><span class="line"><span class="section">scripts_basic:</span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> <span class="variable">$(build)</span>=scripts/basic</span><br><span class="line">	<span class="variable">$(Q)</span>rm -f .tmp_quiet_recordmcount</span><br><span class="line"></span><br><span class="line"><span class="comment"># To avoid any implicit rule to kick in, define an empty command.</span></span><br><span class="line"><span class="section">scripts/basic/%: scripts_basic ;</span></span><br></pre></td></tr></table></figure>

<p>这是scripts_basic 的规则，其对应的命令用到了变量 Q、MAKE 和 build，其中：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Q=@或为空</span><br><span class="line">MAKE=make</span><br></pre></td></tr></table></figure>

<p>变量 build 是在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Kbuild.include#L182">scripts&#x2F;Kbuild.include</a>文件中有定义，定义如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">###</span><br><span class="line"># Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=</span><br><span class="line"># Usage:</span><br><span class="line"># $(Q)$(MAKE) $(build)=dir</span><br><span class="line">build := -f $(srctree)/scripts/Makefile.build obj</span><br></pre></td></tr></table></figure>

<p>经过前面的分析 可知，变量 srctree（<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L201">Makefile · <em>srctree</em></a>） 为”.”，所以有：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">build=-f ./scripts/Makefile.build obj</span><br></pre></td></tr></table></figure>

<p>scripts_basic 展开以后如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">scripts_basic:</span></span><br><span class="line">    @make -f ./scripts/Makefile.build obj=scripts/basic <span class="comment"># 也可以没有@，视配置而定</span></span><br><span class="line">    @rm -f . tmp_quiet_recordmcount <span class="comment"># 也可以没有@</span></span><br></pre></td></tr></table></figure>

<p>scripts_basic 会调用文件.&#x2F;scripts&#x2F;Makefile.build，这个我们后面在分析。</p>
<h4 id="1-4-3-config展开"><a href="#1-4-3-config展开" class="headerlink" title="1.4.3 %config展开"></a><font size=3>1.4.3 %config展开</font></h4><p>上面的几个依赖我们都找到了，接下来吧%config展开：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">%config: scripts_basic outputmakefile FORCE</span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$(MAKE)</span> <span class="variable">$(build)</span>=scripts/kconfig <span class="variable">$@</span></span><br></pre></td></tr></table></figure>

<p>把build的值替换展开后是：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig</span><br></pre></td></tr></table></figure>

<p>发现同样也跟文件.&#x2F;scripts&#x2F;Makefile.build 有关，我们后面再分析此文件。</p>
<h3 id="1-5-编译信息"><a href="#1-5-编译信息" class="headerlink" title="1.5 编译信息"></a><font size=3>1.5 编译信息</font></h3><p>我们在uboot源码目录下执行以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_defconfig </span><br></pre></td></tr></table></figure>

<p>主要是看第二条命令的打印信息：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119220727685.png" alt="image-20241119220727685" />

<p>可以看到里面有两条 make -f 开头的命令：</p>
<ul>
<li>scripts_basic 目标对应的命令</li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make -f ./scripts/Makefile.build obj=scripts/basic</span><br></pre></td></tr></table></figure>

<ul>
<li>%config 目标对应的命令</li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make -f ./scripts/Makefile.build obj=scripts/kconfig mx6ull_14x14_evk_defconfig</span><br></pre></td></tr></table></figure>

<h3 id="1-6-Makefile-build-脚本"><a href="#1-6-Makefile-build-脚本" class="headerlink" title="1.6 Makefile.build 脚本"></a><font size=3>1.6 Makefile.build 脚本</font></h3><p>接下来我们就来看一下Makefile.build 脚本里面都有什么。从前边知道“ make xxx_defconfig“配置 uboot 的时候如下两行命令会执行脚本scripts&#x2F;Makefile.build：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/basic</span><br><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig  </span><br></pre></td></tr></table></figure>

<h4 id="1-6-1-scripts-basic-目标对应的命令"><a href="#1-6-1-scripts-basic-目标对应的命令" class="headerlink" title="1.6.1 scripts_basic 目标对应的命令"></a><font size=3>1.6.1 scripts_basic 目标对应的命令</font></h4><p>scripts_basic 目标对应的命令为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/basic</span><br></pre></td></tr></table></figure>

<ul>
<li>src与prefix变量</li>
</ul>
<p>先看一下<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Makefile.build#L6">scripts&#x2F;Makefile.build</a>最开始的两个变量：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Modified for U-Boot</span></span><br><span class="line">prefix := tpl</span><br><span class="line">src := <span class="variable">$(<span class="built_in">patsubst</span> <span class="variable">$(prefix)</span>/%,%,<span class="variable">$(obj)</span>)</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(obj)</span>,<span class="variable">$(src)</span>)</span><br><span class="line">prefix := spl</span><br><span class="line">src := <span class="variable">$(<span class="built_in">patsubst</span> <span class="variable">$(prefix)</span>/%,%,<span class="variable">$(obj)</span>)</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(obj)</span>,<span class="variable">$(src)</span>)</span><br><span class="line">prefix := .</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>第 2 行，变量 prefix 值为 tpl。</p>
<p>第 3 行定义了变量 src，这里用到了函数 patsubst，此行代码展开后为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">patsubst</span> tpl/%,%, scripts/basic)</span></span><br></pre></td></tr></table></figure>

<p>patsubst 是替换函数，格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(<span class="built_in">patsubst</span> &lt;pattern&gt;,&lt;replacement&gt;,&lt;text&gt;)</span></span><br></pre></td></tr></table></figure>

<p>此函数用于在 text 中查找符合 pattern 的部分，如果匹配的话就用 replacement 替换掉。 pattern 是可以包含通配符“%”，如果 replacement 中也包含通配符“%”，那么 replacement 中的 这个“%”将是 pattern 中的那个“%”所代表的字符串。函数的返回值为替换后的字符串。因 此，第 3 行就是在“scripts&#x2F;basic”中查找符合“tpl&#x2F;%”的部分，然后将“tpl&#x2F;”取消掉，但是 “scripts&#x2F;basic”没有“tpl&#x2F;”，所以 src&#x3D; scripts&#x2F;basic。</p>
<p>第 4 行判断变量 obj 和 src 是否相等，相等的话条件成立，很明显，此处条件成立。</p>
<p>第 6 行和第 3 行一样，只是这里处理的是“spl”，“scripts&#x2F;basic”里面也没有“spl&#x2F;”，所以 src 继续为 scripts&#x2F;basic。</p>
<p>第 8 行因为变量 obj 和 src 相等，所以 prefix&#x3D;. 。</p>
<ul>
<li>kbuild-dir与kbuild-file</li>
</ul>
<p>我们继续往下看<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Makefile.build#L54">scripts&#x2F;Makefile.build</a>，这里有两个变量：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># The filename Kbuild has precedence over Makefile</span></span><br><span class="line">kbuild-dir := <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">filter</span> /%,<span class="variable">$(src)</span>)</span>,<span class="variable">$(src)</span>,<span class="variable">$(srctree)</span>/<span class="variable">$(src)</span>)</span><br><span class="line">kbuild-file := <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">wildcard</span> $(kbuild-<span class="built_in">dir</span>)</span>/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)</span><br><span class="line"><span class="keyword">include</span> $(kbuild-file)</span><br></pre></td></tr></table></figure>

<p>我们前面分析过srctree&#x3D;.，src&#x3D;scripts&#x2F;basic， 将 kbuild-dir 展开后为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kbuild-dir := <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">filter</span> /%, scripts/basic)</span>, scripts/basic, ./scripts/basic)</span><br></pre></td></tr></table></figure>

<p>因为没有以“&#x2F;”为开头的单词，所以$(filter &#x2F;%, scripts&#x2F;basic)的结果为空，kbuild-dir&#x3D;.&#x2F;scripts&#x2F;basic。得到这个变量后，我们将 kbuild-file 展开后为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kbuild-file := <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">wildcard</span> ./scripts/basic/Kbuild)</span>, ./scripts/basic/Kbuild, ./scripts/basic/Makefile)</span><br></pre></td></tr></table></figure>

<p>因为 scrpts&#x2F;basic 目录中没有 Kbuild 这个文件，所以 kbuild-file &#x3D; .&#x2F;scripts&#x2F;basic&#x2F;Makefile。最后将第 4 行展开，即：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">include</span> ./scripts/basic/Makefile</span><br></pre></td></tr></table></figure>

<p>也就是读取 scripts&#x2F;basic 下面的 Makefile 文件。</p>
<ul>
<li>__build</li>
</ul>
<p>我们继续向下看<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Makefile.build#L114">scripts&#x2F;Makefile.build</a>，会看到这个__build：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># We keep a list of all modules in $(MODVERDIR)</span></span><br><span class="line"></span><br><span class="line"><span class="section">__build: $(if <span class="variable">$(KBUILD_BUILTIN)</span>,$(builtin-target) $(lib-target) $(extra-y)) \</span></span><br><span class="line">	 <span class="variable">$(<span class="built_in">if</span> <span class="variable">$(KBUILD_MODULES)</span>,$(obj-m)</span> $(modorder-target)) \</span><br><span class="line">	 $(subdir-ym) <span class="variable">$(always)</span></span><br><span class="line">	@:</span><br></pre></td></tr></table></figure>

<p>__build 是默认目标，因为下面这条命令</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/basic</span><br></pre></td></tr></table></figure>

<p>没有指定目标，所以会使用到默认目标：__build。在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L315">Makefile</a> 中，KBUILD_BUILTIN 为 1，KBUILD_MODULES 为 0，因此展开后目标__build 为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">__build:$(builtin-target) $(lib-target) $(extra-y) $(subdir-ym) <span class="variable">$(always)</span></span></span><br><span class="line">	@:</span><br></pre></td></tr></table></figure>

<p>可以看出目标__build 有 5 个依赖：builtin-target、lib-target、extra-y、subdir-ym 和 always。 这 5 个依赖的具体内容我们就不通过源码来分析了，直接在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Makefile.build#L117">scripts&#x2F;Makefile.build</a> 中输入以下代码：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># We keep a list of all modules in $(MODVERDIR)</span></span><br><span class="line"></span><br><span class="line"><span class="section">__build: $(if <span class="variable">$(KBUILD_BUILTIN)</span>,$(builtin-target) $(lib-target) $(extra-y)) \</span></span><br><span class="line">	 <span class="variable">$(<span class="built_in">if</span> <span class="variable">$(KBUILD_MODULES)</span>,$(obj-m)</span> $(modorder-target)) \</span><br><span class="line">	 $(subdir-ym) <span class="variable">$(always)</span></span><br><span class="line">	@:</span><br><span class="line">	@echo <span class="string">&quot;builtin-target=&quot;</span>$(builtin-target) </span><br><span class="line">	@echo <span class="string">&quot;lib-target=&quot;</span>$(lib-target) </span><br><span class="line">	@echo <span class="string">&quot;extra-y=&quot;</span>$(extra-y)</span><br><span class="line">	@echo <span class="string">&quot;subdir-ym=&quot;</span>$(subdir-ym) </span><br><span class="line">	@echo <span class="string">&quot;always=&quot;</span><span class="variable">$(always)</span></span><br></pre></td></tr></table></figure>

<p>然后我重新执行以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_defconfig </span><br></pre></td></tr></table></figure>

<p>会看到有如下打印信息出现：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">builtin-target=</span><br><span class="line">lib-target=</span><br><span class="line">extra-y=</span><br><span class="line">subdir-ym=</span><br><span class="line">always=scripts/basic/fixdep</span><br></pre></td></tr></table></figure>

<p>可以看出，只有 always 有效，因此__build 最终为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">__build:scripts/basic/fixdep</span></span><br><span class="line">	@:</span><br></pre></td></tr></table></figure>

<p>__build 依赖于 scripts&#x2F;basic&#x2F;fixdep，所以要先编译 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/basic/fixdep.c">scripts&#x2F;basic&#x2F;fixdep.c</a>，生成 fixdep，前面已经读取了 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/basic/Makefile">scripts&#x2F;basic&#x2F;Makefile</a> 文件。</p>
<p>总的来说scripts_basic 目标的作用就是编译出 scripts&#x2F;basic&#x2F;fixdep 这个软件。</p>
<h4 id="1-6-2-config-目标对应的命令"><a href="#1-6-2-config-目标对应的命令" class="headerlink" title="1.6.2 %config 目标对应的命令"></a><font size=3>1.6.2 %config 目标对应的命令</font></h4><p>%config 目标对应的命令为：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig  </span><br></pre></td></tr></table></figure>

<p>按照前面的分析，相关的变量值如下所示：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">src= scripts/kconfig</span><br><span class="line">kbuild-dir = ./scripts/kconfig</span><br><span class="line">kbuild-file = ./scripts/kconfig/Makefile</span><br><span class="line">include ./scripts/kconfig/Makefile</span><br></pre></td></tr></table></figure>

<p>可以看出，Makefilke.build 会读取 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/kconfig/Makefile">scripts&#x2F;kconfig&#x2F;Makefile</a> 中的内容，此文件中有如下所示内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">%_defconfig: <span class="variable">$(obj)</span>/conf</span></span><br><span class="line">	<span class="variable">$(Q)</span><span class="variable">$&lt;</span> <span class="variable">$(silent)</span> --defconfig=arch/<span class="variable">$(SRCARCH)</span>/configs/<span class="variable">$@</span> <span class="variable">$(Kconfig)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Added for U-Boot (backward compatibility)</span></span><br><span class="line"><span class="section">%_config: %_defconfig</span></span><br><span class="line">	@:</span><br></pre></td></tr></table></figure>

<p>这几行在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/kconfig/Makefile#L127">scripts&#x2F;kconfig&#x2F;Makefile · <em>%_defconfig</em></a> 附近。目标%_defconfig 刚好和我们输入的 xxx_defconfig 匹配，所以会执行这条规则。依赖为 $(obj)&#x2F;conf，展开后就是 scripts&#x2F;kconfig&#x2F;conf。</p>
<p>接下来就是检查并生成依赖 scripts&#x2F;kconfig&#x2F;conf。 conf 是主机软件，到这里我们就停下来，不要纠结 conf 是怎么编译出来的，否则就越陷越深，太绕了，像 conf 这种主机所使用的工具类软件我们一般不关心它是如何编译产生的。如果一定要看是 conf 是怎么生成的，可以输入如下命令重新配置 uboot，在重新配置 uboot 的过程中就会 输出 conf 编译信息。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_defconfig </span><br></pre></td></tr></table></figure>

<p>会有下面的打印信息：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">  cc -Wp,-MD,scripts/kconfig/.zconf.tab.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer  -std=gnu11   -D_GNU_SOURCE -D_DEFAULT_SOURCE -I/usr/include/ncursesw -DCURSES_LOC=&quot;&lt;ncurses.h&gt;&quot; -DNCURSES_WIDECHAR=1 -DLOCALE  -Iscripts/kconfig -c -o scripts/kconfig/zconf.tab.o scripts/kconfig/zconf.tab.c</span><br><span class="line">  cc  -o scripts/kconfig/conf scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o</span><br><span class="line">scripts/kconfig/conf  --defconfig=arch/../configs/mx6ull_14x14_evk_defconfig Kconfig</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"></span></span><br><span class="line"><span class="language-bash"><span class="comment"># configuration written to .config</span></span></span><br><span class="line"><span class="meta prompt_">#</span></span><br></pre></td></tr></table></figure>

<p>这里的cc  -o scripts&#x2F;kconfig&#x2F;conf这行就是在编译生成conf软件。得到 scripts&#x2F;kconfig&#x2F;conf 以后就要执行目标%_defconfig 的命令：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(Q)</span><span class="variable">$&lt;</span> <span class="variable">$(silent)</span> --defconfig=arch/<span class="variable">$(SRCARCH)</span>/configs/<span class="variable">$@</span> <span class="variable">$(Kconfig)</span></span><br></pre></td></tr></table></figure>

<p>相关的变量值如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">silent=-s 或为空</span><br><span class="line">SRCARCH=..</span><br><span class="line">Kconfig=Kconfig</span><br></pre></td></tr></table></figure>

<p>将其展开就是：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@ scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig</span><br></pre></td></tr></table></figure>

<p>上述命令用到了 xxx_defconfig 文件，比如 mx6ull_14x14_evk_defconfig 。这里会将mx6ull_14x14_evk_defconfig 中的配置输出到.config 文件中，最终生成 uboot 根目录下的.config 文件。</p>
<h3 id="1-7-总结一下"><a href="#1-7-总结一下" class="headerlink" title="1.7 总结一下"></a><font size=3>1.7 总结一下</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119221119307.png" alt="image-20241119221119307" />

<h2 id="2-u-boot-bin的生成过程"><a href="#2-u-boot-bin的生成过程" class="headerlink" title="2. u-boot.bin的生成过程"></a><font size=3>2. u-boot.bin的生成过程</font></h2><h3 id="2-1-目标文件"><a href="#2-1-目标文件" class="headerlink" title="2.1 目标文件"></a><font size=3>2.1 目标文件</font></h3><p>配置好 uboot 以后就可以直接 make 编译了，因为没有指明目标，所以会使用默认目标，主 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L126">Makefile</a> 中的默认目标如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># That&#x27;s our default target when none is given on the command line</span></span><br><span class="line">PHONY := _all</span><br><span class="line"><span class="section">_all:</span></span><br></pre></td></tr></table></figure>

<p>目标_all 又依赖于 all，在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L192">Makefile</a> 中如下所示 ：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># If building an external module we do not care about the all: rule</span></span><br><span class="line"><span class="comment"># but instead _all depend on modules</span></span><br><span class="line">PHONY += all</span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(KBUILD_EXTMOD)</span>,)</span><br><span class="line"><span class="section">_all: all</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="section">_all: modules</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>如果 KBUILD_EXTMOD 为空的话 _all 依赖于 all 。这里不是单独编译模块，所以KBUILD_EXTMOD 为空， _all 的依赖就是 all。</p>
<h3 id="2-2-all目标规则"><a href="#2-2-all目标规则" class="headerlink" title="2.2 all目标规则"></a><font size=3>2.2 all目标规则</font></h3><p>在主 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L921">Makefile</a> 中 all 目标规则如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">all:		$(ALL-y)</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(CONFIG_DM_I2C_COMPAT)</span><span class="variable">$(CONFIG_SANDBOX)</span>,y)</span><br><span class="line">	@echo &gt;&amp;2 <span class="string">&quot;===================== WARNING ======================&quot;</span></span><br><span class="line">	@echo &gt;&amp;2 <span class="string">&quot;This board uses CONFIG_DM_I2C_COMPAT. Please remove&quot;</span></span><br><span class="line">	@echo &gt;&amp;2 <span class="string">&quot;(possibly in a subsequent patch in your series)&quot;</span></span><br><span class="line">	@echo &gt;&amp;2 <span class="string">&quot;before sending patches to the mailing list.&quot;</span></span><br><span class="line">	@echo &gt;&amp;2 <span class="string">&quot;====================================================&quot;</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="comment">#......</span></span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line">	@<span class="comment"># Check that this build does not use CONFIG options that we do not</span></span><br><span class="line">	@<span class="comment"># know about unless they are in Kconfig. All the existing CONFIG</span></span><br><span class="line">	@<span class="comment"># options are whitelisted, so new ones should not be added.</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> cmd,cfgcheck,u-boot.cfg)</span></span><br></pre></td></tr></table></figure>

<p>all里面其实是大量的打印信息，主要还是要看它的依赖$(ALL-y)。</p>
<h3 id="2-3-ALL-y"><a href="#2-3-ALL-y" class="headerlink" title="2.3 ALL-y"></a><font size=3>2.3 ALL-y</font></h3><p>在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L810">Makefile</a> 中， ALL-y 如下  :</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Always append ALL so that arch config.mk&#x27;s can add custom ones</span></span><br><span class="line">ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map binary_size_check</span><br><span class="line"></span><br><span class="line">ALL-<span class="variable">$(CONFIG_ONENAND_U_BOOT)</span> += u-boot-onenand.bin</span><br><span class="line"><span class="comment">#......</span></span><br><span class="line">ALL-<span class="variable">$(CONFIG_OF_HOSTFILE)</span> += u-boot.dtb</span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(CONFIG_SPL_TARGET)</span>,)</span><br><span class="line">ALL-<span class="variable">$(CONFIG_SPL)</span> += $(CONFIG_SPL_TARGET:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="comment">#......</span></span><br><span class="line"><span class="comment"># Add optional build target if defined in board/cpu/soc headers</span></span><br><span class="line"><span class="keyword">ifneq</span> (<span class="variable">$(CONFIG_BUILD_TARGET)</span>,)</span><br><span class="line">ALL-y += $(CONFIG_BUILD_TARGET:<span class="string">&quot;%&quot;</span>=%)</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"><span class="comment">#......</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(CONFIG_MPC85xx)</span><span class="variable">$(CONFIG_OF_SEPARATE)</span>,yy)</span><br><span class="line">ALL-y += u-boot-with-dtb.bin</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>可以看出， ALL-y一定包含 u-boot.srec、 u-boot.bin、 u-boot.sym、System.map、 u-boot.cfg 和 binary_size_check 这几个文件。根据 uboot 的配置情况也可能包含其他的文件，比如：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALL-<span class="variable">$(CONFIG_ONENAND_U_BOOT)</span> += u-boot-onenand.bin</span><br></pre></td></tr></table></figure>

<p>CONFIG_ONENAND_U_BOOT 就是 uboot 中跟 ONENAND 配置有关的，如果我们使能了ONENAND，那么在.config 配置文件中就会有“CONFIG_ONENAND_U_BOOT&#x3D;y”这一句。相当于 CONFIG_ONENAND_U_BOOT 是个变量，这个变量的值为“y”，所以展开以后就是：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALL-y += u-boot-onenand.bin</span><br></pre></td></tr></table></figure>

<p>这个就是.config 里面的配置参数的含义，这些参数其实都是变量，后面跟着变量值，会在顶层 Makefile 或者其他 Makefile 中调用这些变量。</p>
<h3 id="2-4-u-boot-bin"><a href="#2-4-u-boot-bin" class="headerlink" title="2.4 u-boot.bin"></a><font size=3>2.4 u-boot.bin</font></h3><p>ALL-y 里面有个 u-boot.bin，这个就是我们最终需要的 uboot 二进制可执行文件，所作的所有工作就是为了它。在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1034">Makefile</a> 中找到 u-boot.bin 目标对应的规则，如下所示：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(CONFIG_MULTI_DTB_FIT)</span>,y)</span><br><span class="line"></span><br><span class="line"><span class="section">fit-dtb.blob: dts/dt.dtb FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,mkimage)</span></span><br><span class="line"></span><br><span class="line">MKIMAGEFLAGS_fit-dtb.blob = -f auto -A <span class="variable">$(ARCH)</span> -T firmware -C none -O u-boot \</span><br><span class="line">	-a 0 -e 0 -E \</span><br><span class="line">	<span class="variable">$(<span class="built_in">patsubst</span> %,-b arch/<span class="variable">$(ARCH)</span>/dts/%.dtb,$(<span class="built_in">subst</span> &quot;,,<span class="variable">$(CONFIG_OF_LIST)</span>)</span>) -d /dev/null</span><br><span class="line"></span><br><span class="line"><span class="section">u-boot-fit-dtb.bin: u-boot-nodtb.bin fit-dtb.blob</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,cat)</span></span><br><span class="line"></span><br><span class="line"><span class="section">u-boot.bin: u-boot-fit-dtb.bin FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,copy)</span></span><br><span class="line"><span class="keyword">else</span> <span class="keyword">ifeq</span> (<span class="variable">$(CONFIG_OF_SEPARATE)</span>,y)</span><br><span class="line"><span class="section">u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,cat)</span></span><br><span class="line"></span><br><span class="line"><span class="section">u-boot.bin: u-boot-dtb.bin FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,copy)</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="section">u-boot.bin: u-boot-nodtb.bin FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,copy)</span></span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>可以搜索一下这个CONFIG_MULTI_DTB_FIT，会发现是没有这个配置项的：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$ grep -nRw &quot;CONFIG_MULTI_DTB_FIT&quot; ./</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">......</span></span><br><span class="line">./.config:654:# CONFIG_MULTI_DTB_FIT is not set</span><br></pre></td></tr></table></figure>

<p>所以走的是else这部分，我们再搜一下CONFIG_OF_SEPARATE：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sumu@sumu-virtual-machine:~/7Linux/imx6ull-uboot$ grep -nRw &quot;CONFIG_OF_SEPARATE&quot; ./</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">......</span></span><br><span class="line">./.config:649:CONFIG_OF_SEPARATE=y</span><br></pre></td></tr></table></figure>

<p>判断 CONFIG_OF_SEPARATE 是否等于 y，如果相等，那条件就成立。所以在这里是成立的。所以这一大段最后就是：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,cat)</span></span><br><span class="line"></span><br><span class="line"><span class="section">u-boot.bin: u-boot-dtb.bin FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,copy)</span></span><br></pre></td></tr></table></figure>

<p>这部分就是制作u-boot-dtb.bin和u-boot.bin的规则，目标u-boot.bin依赖于u-boot-dtb.bin，命令为$(call if_changed,copy) ， 这里调用了 if_changed ，if_changed 是一个函数 ，这个函数在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Kbuild.include#L258">scripts&#x2F;Kbuild.include</a> 中有定义。而顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L345">Makefile</a> 中会包含 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Kbuild.include">scripts&#x2F;Kbuild.include</a> 文件，这个前面已经说过了。  if_changed 在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Kbuild.include#L258">scripts&#x2F;Kbuild.include</a>  中的定义如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">if_changed = <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">strip</span> $(any-prereq)</span> $(arg-check)),                       \</span><br><span class="line">	@set -e;                                                             \</span><br><span class="line">	$(echo-cmd) $(cmd_$(1));                                             \</span><br><span class="line">	printf &#x27;%s\n&#x27; &#x27;cmd_<span class="variable">$@</span> := $(make-cmd)&#x27; &gt; $(dot-target).cmd)</span><br></pre></td></tr></table></figure>

<p>这里有一些关于if_changed的描述在<a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/scripts/Kbuild.include#L228">scripts&#x2F;Kbuild.include</a>：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###</span></span><br><span class="line"><span class="comment"># if_changed      - execute command if any prerequisite is newer than</span></span><br><span class="line"><span class="comment">#                   target, or command line has changed</span></span><br><span class="line"><span class="comment"># if_changed_dep  - as if_changed, but uses fixdep to reveal dependencies</span></span><br><span class="line"><span class="comment">#                   including used config symbols</span></span><br><span class="line"><span class="comment"># if_changed_rule - as if_changed but execute rule instead</span></span><br><span class="line"><span class="comment"># See Documentation/kbuild/makefiles.txt for more info</span></span><br></pre></td></tr></table></figure>

<p>根据描述，在一些先决条件比目标新的时候，或者命令行有改变的时候， if_changed 就会执行一些命令。继续往后看就可以找到刚才的定义：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">if_changed = <span class="variable">$(<span class="built_in">if</span> $(<span class="built_in">strip</span> $(any-prereq)</span> $(arg-check)),                       \</span><br><span class="line">	@set -e;                                                             \</span><br><span class="line">	$(echo-cmd) $(cmd_$(1));                                             \</span><br><span class="line">	printf &#x27;%s\n&#x27; &#x27;cmd_<span class="variable">$@</span> := $(make-cmd)&#x27; &gt; $(dot-target).cmd)</span><br></pre></td></tr></table></figure>

<p>这里是函数 if_changed， if_changed 函数引用的变量比较多，也比较绕，我们只需要知道它可以从 u-boot-dtb.bin 生成 u-boot.bin 就行了。  </p>
<h3 id="2-5-u-boot-dtb-bin"><a href="#2-5-u-boot-dtb-bin" class="headerlink" title="2.5 u-boot-dtb.bin"></a><font size=3>2.5 u-boot-dtb.bin</font></h3><h4 id="2-5-1-依赖目标"><a href="#2-5-1-依赖目标" class="headerlink" title="2.5.1 依赖目标"></a><font size=3>2.5.1 依赖目标</font></h4><p>既然 u-boot.bin 依赖于 u-boot-dtb.bin，那么肯定要先生成 u-boot-dtb.bin 文件，顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1037">Makefile</a> 中相关代码如下：    </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,cat)</span></span><br></pre></td></tr></table></figure>

<p>目标 u-boot-dtb.bin 又依赖于 u-boot-nodtb.bin， u-boot-nodtb.bin的规则在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1126">Makefile</a>中如下所示：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">u-boot-nodtb.bin: u-boot FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed,objcopy)</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> DO_STATIC_RELA,<span class="variable">$&lt;</span>,<span class="variable">$@</span>,<span class="variable">$(CONFIG_SYS_TEXT_BASE)</span>)</span></span><br><span class="line">	<span class="variable">$(BOARD_SIZE_CHECK)</span></span><br></pre></td></tr></table></figure>

<p>可以看到u-boot-nodtb.bin又依赖于u-boot。</p>
<h4 id="2-5-2-u-boot"><a href="#2-5-2-u-boot" class="headerlink" title="2.5.2 u-boot"></a><font size=3>2.5.2 u-boot</font></h4><h5 id="2-5-2-1-u-boot的依赖"><a href="#2-5-2-1-u-boot的依赖" class="headerlink" title="2.5.2.1 u-boot的依赖"></a><font size=3>2.5.2.1 u-boot的依赖</font></h5><p>u-boot的规则在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1504">Makefile</a> 中相关规则如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">u-boot:	$(u-boot-init) $(u-boot-main) u-boot.lds FORCE</span></span><br><span class="line">	+<span class="variable">$(<span class="built_in">call</span> if_changed,u-boot__)</span></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(CONFIG_KALLSYMS)</span>,y)</span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> cmd,smap)</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> cmd,u-boot__)</span> common/system_map.o</span><br><span class="line"><span class="keyword">endif</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ifeq</span> (<span class="variable">$(CONFIG_RISCV)</span>,y)</span><br><span class="line">	@tools/prelink-riscv <span class="variable">$@</span> 0</span><br><span class="line"><span class="keyword">endif</span></span><br></pre></td></tr></table></figure>

<p>可以看到目标 u-boot 依赖于 u-boot-init、 u-boot-main 和 u-boot.lds， u-boot-init 和 u-boot-main 是两个变量，在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L749">Makefile</a> 中有定义，值如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">u-boot-init := $(head-y)</span><br><span class="line">u-boot-main := $(libs-y)</span><br></pre></td></tr></table></figure>

<h5 id="2-5-2-2-head-y"><a href="#2-5-2-2-head-y" class="headerlink" title="2.5.2.2 head-y"></a><font size=3>2.5.2.2 head-y</font></h5><p>$(head-y)跟 CPU 架构有关，我们使用的是 ARM 芯片，所以 head-y 在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/arch/arm/Makefile#L94">arch&#x2F;arm&#x2F;Makefile</a> 中被指定为：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">head-y := arch/arm/cpu/<span class="variable">$(CPU)</span>/start.o</span><br></pre></td></tr></table></figure>

<p>根据本篇笔记 “第一部分 第11.3 变量导出” 小节，我们知道 CPU&#x3D;armv7，因此 head-y 展开以后就是：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">head-y := arch/arm/cpu/armv7/start.o</span><br></pre></td></tr></table></figure>

<p>所以就有：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">u-boot-init= arch/arm/cpu/armv7/start.o</span><br></pre></td></tr></table></figure>

<h5 id="2-5-2-3-libs-y"><a href="#2-5-2-3-libs-y" class="headerlink" title="2.5.2.3 libs-y"></a><font size=3>2.5.2.3 libs-y</font></h5><p>$(libs-y)在顶层 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L688">Makefile</a> 中被定义为 uboot 所有子目录下 build-in.o 的集合，代码如下：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">libs-y += lib/</span><br><span class="line">libs-<span class="variable">$(HAVE_VENDOR_COMMON_LIB)</span> += board/<span class="variable">$(VENDOR)</span>/common/</span><br><span class="line">libs-<span class="variable">$(CONFIG_OF_EMBED)</span> += dts/</span><br><span class="line">libs-y += fs/</span><br><span class="line">libs-y += net/</span><br><span class="line"><span class="comment"># ......</span></span><br><span class="line">u-boot-dirs	:= <span class="variable">$(<span class="built_in">patsubst</span> %/,%,$(<span class="built_in">filter</span> %/, $(libs-y)</span>)) tools examples</span><br><span class="line"></span><br><span class="line">u-boot-alldirs	:= <span class="variable">$(<span class="built_in">sort</span> $(u-boot-dirs)</span> <span class="variable">$(<span class="built_in">patsubst</span> %/,%,$(<span class="built_in">filter</span> %/, $(libs-)</span>)))</span><br><span class="line"></span><br><span class="line">libs-y		:= <span class="variable">$(<span class="built_in">patsubst</span> %/, %/built-in.o, $(libs-y)</span>)</span><br></pre></td></tr></table></figure>

<p>从上面的代码可以看出， libs-y 都是 uboot 各子目录的集合，最后：  </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">libs-y := <span class="variable">$(<span class="built_in">patsubst</span> %/, %/built-in.o, $(libs-y)</span>)</span><br></pre></td></tr></table></figure>

<p>这里调用了函数 patsubst，将 libs-y 中的“&#x2F;”替换为”&#x2F;built-in.o”，比如“drivers&#x2F;dma&#x2F;”就变为了“drivers&#x2F;dma&#x2F;built-in.o”，相当于将 libs-y 改为所有子目录中 built-in.o 文件的集合。那么 uboot-main 就等于所有子目录中 built-in.o 的集合。  </p>
<h5 id="2-5-2-4-u-boot-lds规则"><a href="#2-5-2-4-u-boot-lds规则" class="headerlink" title="2.5.2.4 u-boot.lds规则"></a><font size=3>2.5.2.4 u-boot.lds规则</font></h5><p>上面的这个 u-boot 规则就相当于将以 u-boot.lds 为链接脚本，将 arch&#x2F;arm&#x2F;cpu&#x2F;armv7&#x2F;start.o 和各个子目录下的 built-in.o 链接在一起生成 u-boot。u-boot.lds 的规则在 <a target="_blank" rel="noopener" href="https://gitee.com/sumumm/u-boot/blob/master/Makefile#L1655">Makefile</a> 中是这样的：</p>
 <figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">u-boot.lds: <span class="variable">$(LDSCRIPT)</span> prepare FORCE</span></span><br><span class="line">	<span class="variable">$(<span class="built_in">call</span> if_changed_dep,cpp_lds)</span></span><br></pre></td></tr></table></figure>

<h5 id="2-5-2-5-built-in-o怎么生成？"><a href="#2-5-2-5-built-in-o怎么生成？" class="headerlink" title="2.5.2.5  built-in.o怎么生成？"></a><font size=3>2.5.2.5  built-in.o怎么生成？</font></h5><p>接下来的重点就是各子目录下的 built-in.o 是怎么生成的，以 drivers&#x2F;gpio&#x2F;built-in.o 为例，在drivers&#x2F;gpio&#x2F;目录下会有个名为.built-in.o.cmd 的文件： </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119231818010.png" alt="image-20241119231818010" />

<p>此文件内容如下： </p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cmd_drivers/gpio/built-in.o :=  arm-linux-gnueabihf-ld.bfd     -r -o drivers/gpio/built-in.o drivers/gpio/gpio-uclass.o drivers/gpio/74x164_gpio.o drivers/gpio/mxc_gpio.o </span><br></pre></td></tr></table></figure>

<p>从命令“cmd_drivers&#x2F;gpio&#x2F;built-in.o”可以看出， drivers&#x2F;gpio&#x2F;built-in.o 这个文件是使用 ld 命令由文件 drivers&#x2F;gpio&#x2F;mxc_gpio.o 还有另外两个.o生成而来的，其中 mxc_gpio.o 是 mxc_gpio.c 编译生成的.o 文件，其他两个也类似，这个是 NXP 的 I.MX 系列的 GPIO 驱动文件。这里用到了 ld 的“-r”参数，参数含义如下：-r –relocateable: 产生可重定向的输出，比如，产生一个输出文件它可再次作为‘ld’ 的输入，这经常被叫做“部分链接”，当我们需要将几个小的.o 文件链接成为一个.o 文件的时候，需要使用此选项。  </p>
<h5 id="2-5-2-6-u-boot的生成"><a href="#2-5-2-6-u-boot的生成" class="headerlink" title="2.5.2.6 u-boot的生成"></a><font size=3>2.5.2.6 u-boot的生成</font></h5><p>最终将各个子目录中的 built-in.o 文件链接在一起就形成了 u-boot，使用如下命令编译 uboot就可以看到链接的过程：  </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean</span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_defconfig </span><br><span class="line">make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16</span><br></pre></td></tr></table></figure>

<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20241119232614054.png" alt="image-20241119232614054" />

<p>将其整理一下，内容如下：  </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">arm-linux-gnueabihf-ld.bfd   -pie  --gc-sections -Bstatic  --no-dynamic-linker -Ttext 0x87800000 \</span><br><span class="line">-o u-boot -T u-boot.lds \</span><br><span class="line">arch/arm/cpu/armv7/start.o --start-group  \</span><br><span class="line">arch/arm/cpu/built-in.o  \</span><br><span class="line">arch/arm/cpu/armv7/built-in.o  \</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">......</span></span><br><span class="line">lib/built-in.o  \</span><br><span class="line">net/built-in.o --end-group \</span><br><span class="line">arch/arm/lib/eabi_compat.o  \</span><br><span class="line">arch/arm/lib/lib.a \</span><br><span class="line">-Map u-boot.map;  \</span><br><span class="line">true</span><br></pre></td></tr></table></figure>

<p>可以看出最终是用 arm-linux-gnueabihf-ld.bfd 命令将 arch&#x2F;arm&#x2F;cpu&#x2F;armv7&#x2F;start.o 和其他众多的 built_in.o 链接在一起，形成 u-boot。目标 all 除了 u-boot.bin 以外还有其他的依赖，比如 u-boot.srec 、 u-boot.sym 、 System.map、u-boot.cfg 和 binary_size_check 等等，这些依赖的生成方法和 u-boot.bin 很类似，这里就不再详细说明了。  </p>
<h3 id="2-6-总结一下"><a href="#2-6-总结一下" class="headerlink" title="2.6 总结一下"></a><font size=3>2.6 总结一下</font></h3><p>这个图是按照uboot 2016.03画的，2019.04有所不同，2019.04使用设备树了，但是流程大概都是一样的。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/02IMX6ULL%E5%B9%B3%E5%8F%B0/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/LV05-02-U-Boot-06-01-%E9%A1%B6%E5%B1%82Makefile%E5%9F%BA%E7%A1%80%E8%A7%A3%E6%9E%90/img/image-20230730143850408.png" alt="image-20230730143850408" style="zoom:50%;" />

<p>make xxx_defconfig： 用于配置 uboot，这个命令最主要的目的就是生成.config 文件。<br>make：用于编译 uboot，这个命令的主要工作就是生成二进制的 u-boot.bin 文件和其他的一些与 uboot 有关的文件，比如 u-boot.imx 等等。  </p>

    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/ca32061f.html">LV05-02-U-Boot-06-01-顶层Makefile基础解析</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2024年11月19日 - 23:38</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/ca32061f.html" title="LV05-02-U-Boot-06-01-顶层Makefile基础解析">https://sumumm.github.io/post/ca32061f.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV05-%E7%B3%BB%E7%BB%9F%E9%95%9C%E5%83%8F/" rel="tag"><i class="fa fa-tag"></i> LV05-系统镜像</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/d00e99b.html" rel="prev" title="LV05-03-Kernel-01-NXP-linux">
                  <i class="fa fa-angle-left"></i> LV05-03-Kernel-01-NXP-linux
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/67dde56a.html" rel="next" title="LV05-02-U-Boot-05-uboot下自定义一个命令">
                  LV05-02-U-Boot-05-uboot下自定义一个命令 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
